## operator

Started by
13 comments, last by kloffy 17 years, 7 months ago
So, I was messing around with the ## operator a bit, (I'm pretty new to it), and was having some troubles. I was trying to use the ## operate to create a default object name. The macro I made is:

#define		CreateObjName(or,n,c)	{(or) = ((n)##(c)); ++(c);}

Now, when I try to call this later...

fGameObject::fGameObject() : m_id(id_count), m_type(OBJ_DEFAULT_OBJ)
{
	CreateObjName( m_name, default_name, obj_count );
	++id_count;
}

// m_name is a const char*
// default_name is a const char*
// obj_count is an unsigned int

I get the following error: error C2064: term does not evaluate to a function taking 1 arguments Anyone know why I would be receiving this? Thanks in advance!
Advertisement
Expand the macro. It becomes

fGameObject::fGameObject() : m_id(id_count), m_type(OBJ_DEFAULT_OBJ){        {(m_name) = ((default_name)(obj_count)); ++(obj_count);}	++id_count;}


The error is telling you that (default_name) does not evaluate to a function taking 1 argument. The argument being obj_count.
Ah, I see. So, since this is all done at compile time, it just takes the input and tries to concatenate those, rather than the values of the inputs.

I take it the ## operator is then the wrong thing to use in this situation?
Quote:Original post by ETFBlade
I take it the ## operator is then the wrong thing to use in this situation?
I gather from the syntax that this is C++, in which case you should really be using std::string. With a little help from Boost, your example becomes:
m_name = default_name + boost::lexical_cast<std::string>(obj_count++);
Even in C, it would probably be better to use a function instead of a macro, implemented using appropriate C library functions such as strcat().

But in C++, just use std::string.
The *preprocessor* is the wrong thing to be trying to use, because it operates on the *text of your program*, *before compile time* and *has actually has almost no concept of the C++ language at all*.

jyk++.
The ## operator is only useful for generating variable names, function names or other things that need to be done at compile time. It won't work for what you are trying to do (concatenate two string variables together).

Here is how I would use it:

#define FUNCTION_TIMER_BEGIN()	static int __FUNCTION__##_timer = 0;	static int __FUNCTION__##_total_time = 0;	timer = time(NULL);#define FUNCTION_TIMER_END()	__FUNCTION__##_total_time += time(NULL) - __FUNCTION__##_timer;	__FUNCTION__##_timer = 0;


This snippet uses the ## macro to generate variable names by concatenating the calling function's name with _timer or _total_time.

BTW, does anyone know how to stop this forum software from removing the newlines when writing multi-line macros?

[Edited by - deathkrush on September 14, 2006 11:13:13 PM]
deathkrushPS3/Xbox360 Graphics Programmer, Mass Media.Completed Projects: Stuntman Ignition (PS3), Saints Row 2 (PS3), Darksiders(PS3, 360)
Quote:Original post by deathkrush
The ## operator is only useful for generating variable names, function names or other things that need to be done at compile time.
Quote:Original post by Zahlman
The *preprocessor* is the wrong thing to be trying to use, because it operates on the *text of your program*, *before compile time* and *has actually has almost no concept of the C++ language at all*.


Once more, with feeling: the preprocessor operates on the text of your program before compile time.

This Public Service Announcement brought to you by the Coalition of Natively Reflection-Capable Programming Languages. The CNR-CPL encourages you to stop writing hackish C++ and just use a Real Language™ when you need one. Please code responsibly.
Quote:Original post by Oluseyi
Once more, with feeling: the preprocessor operates on the text of your program before compile time.


I meant that you usually use the preprocessor to generate things that are needed at compile time. Of course, the preprocessor itself runs before compile time... details, details, details...
deathkrushPS3/Xbox360 Graphics Programmer, Mass Media.Completed Projects: Stuntman Ignition (PS3), Saints Row 2 (PS3), Darksiders(PS3, 360)
Quote:Original post by deathkrush
details, details, details...


The devil is in the details.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
The preprocessor is textual replacement - but it's far from straightforward.

For a start, it respects string literals and comments (and trigraph replacement happens before the preprocessor runs).

What would you expect the following to print, and why?
int max(int x, int y){    return 0;}#define max(x,y)  (((x) > (y)) ? (x) : (y))#include <iostream>int main(){    std::cout << (max)(4,5);    std::cout << std::endl;    std::cout << max(4,5);}

This topic is closed to new replies.

Advertisement