Skip to main content
GameDev.net gamedev.net
🔒 Locked 🎲 GameMaker

## operator

Started by ETFBlade Sep 14, 2006 at 9:05 PM 13 replies 1.8k views
Original Post
ETFBlade
ETFBlade
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!
Deyja
Deyja
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.
ETFBlade
ETFBlade
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?
Zakwayda
Zakwayda
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.
Zahlman
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*.

jyk++.
deathkrush
deathkrush
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)
Oluseyi
Oluseyi
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.
deathkrush
deathkrush
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)
Fruny
Fruny
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
Nitage
Nitage
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);}
Deyja
Deyja
It will print 'Error C#####: Too few arguments to macro'

Incidentally, you don't need a special operator to concatanate strings.

const char* ugly_c_string = "These strings" "will be concatanated" "automatically" "by the compiler";
ETFBlade
ETFBlade
Thanks everyone for clarifying. The ## operator was pretty new to me, but I feel like I have a pretty good grasp of it now.
kloffy
kloffy
Does anybody have some more info about this ## operator? I've never heard of it before. It looks interesting and, thanks to this thread, I have a rough idea what it does. I would like to see some documentation about it.
kloffy
kloffy
Ah, so that's what it's called. Intersting stuff, thanks!

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.