Sign in to follow this  

## operator

This topic is 4108 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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!

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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++.

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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...

Share this post


Link to post
Share on other sites
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);
}



Share this post


Link to post
Share on other sites
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";

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

This topic is 4108 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this