meaning of define

B

Bart

What is meaning of the following define:-

#define x(argl...) x1(##argl)

I don't think variadic macros are allowed in C++, so the ... part is
not standard. The ## is the token pasting operator. It pastes the token
that you pass as an argument. For example the macro

#define var(n) var##n

would cause 'var(3)' to be expanded to 'var3'.

Regards,
Bart.
 
N

niraj.tiwari

Bart said:
I don't think variadic macros are allowed in C++, so the ... part is
not standard. The ## is the token pasting operator. It pastes the token
that you pass as an argument. For example the macro

#define var(n) var##n

would cause 'var(3)' to be expanded to 'var3'.

Regards,
Bart.

I have tried this and this compiles on c++ compiler but if you try
something like
#define x(argl,...) x1(##arl)
or
#define x(...) x1(##)
compiler throws error. So can you explain how this is being expanded? I
think normal syntax of variable number of argument is foo(some arg,...)
or simply foo(...).
Thanks,
Niraj
 
F

flamexx7

## operator in C++ is used inside macros to concatenate two tokens for
example :-

#include <iostream>
using namespace std;
#define func(x) x##out<<"Hello!"<<endl

int main(){
func(c);
system("pause");
}

Above programme will print Hello! on screen.
 
F

Frederick Gotham

flamexx7 posted:
## operator in C++ is used inside macros to concatenate two tokens


It's nothing to do with the C++ language itself -- it's purely to do with the
preprocessor.
 
B

Bart

I have tried this and this compiles on c++ compiler

That your compiler has accepted it doesn't mean that it's standard C++.
IIRC the C99 standard allows variadic macros, and some compilers have
accepted them prior to that, but that doesn't make it legal C++.

I think normal syntax of variable number of argument is foo(some arg,...)
or simply foo(...).

No, the second foo is not valid. Functions with a variable number of
arguments must have at least one formal argument for the va_start macro
to work. Again, some compilers have extensions that allow foo(...), but
that's not standard C++.

Regards,
Bart.
 
B

Bart

Frederick said:
flamexx7 posted:


It's nothing to do with the C++ language itself -- it's purely to do with the
preprocessor.

Well, the standard which defines the C++ language also defines the
preprocessor, so from a purely formal point of view the preprocessor IS
part of the language. The reasons for which people think of the
preprocessor as a separate entity from the language are mostly
historical and practical.

Regards,
Bart.
 
R

Rolf Magnus

Frederick said:
flamexx7 posted:



It's nothing to do with the C++ language itself -- it's purely to do with
the preprocessor.

The preprocessor is part of the C++ language.
 
F

Frederick Gotham

Rolf Magnus posted:
The preprocessor is part of the C++ language.


Yes, but the _actual_ C++ compiler doesn't know anything about #define... all
of that has been stripped away in the preprocessor phase.
 
O

osmium

Frederick Gotham said:
Rolf Magnus posted:



Yes, but the _actual_ C++ compiler doesn't know anything about #define...
all
of that has been stripped away in the preprocessor phase.

Couldn't you just admit that you shouldn't have made your initial post and
let it go at that? It is not necessary that you respond to each and every
message. AFAIK the preprocessor is a *conceptual* phase. Conceptual means
"not real".
 
F

Frederick Gotham

osmium posted:
Couldn't you just admit that you shouldn't have made your initial post
and let it go at that?


No, I believe my initial post my appropriate. Just today we had someone
asking why their "#define" struct wouldn't compile properly.
 
B

Bart

Frederick said:
Rolf Magnus posted:


Yes, but the _actual_ C++ compiler doesn't know anything about #define... all
of that has been stripped away in the preprocessor phase.

The C++ standard doesn't say how the actual C++ compiler has to be
structured. It only talks about requirements on implementation. The
implementation is only required to behave _as if_ all phases of
translation occur, but whether the phases physically occur in separate
steps is not specified.

Actually, preprocessing is itself divided into two translation phases,
and several other phases which are not usually thought of as such also
occur (e.g. mapping source characters and folding line continuations
are two separate phases). Like I said previously, preprocessing is
viewed as a separate part of the translation process for historical
reasons and because it is practical to think of it as such.

Regards,
Bart.
 
J

Jerry Coffin

[ ... ]
Couldn't you just admit that you shouldn't have made your initial post and
let it go at that? It is not necessary that you respond to each and every
message. AFAIK the preprocessor is a *conceptual* phase. Conceptual means
"not real".

Not really. The phases of translation are entirely real, and later
phases really can't take actions based on the source code as it existed
before a previous phase of translation did its thing.

It is true that there's no requirement that the phases of translation
necessarily produce successive versions of the source code, nor that the
version of the source code that would be the output of a given phase
necessarily exist at any point. Nonetheless, in the compilers I've
looked at, the preprocessor and compiler are distinct to at least some
degree. In some cases, they're entirely separate programs, while in
others they're compiled into a single program, but still operate
separately from each other.
 
B

Bart

Jerry Coffin wrote:
It is true that there's no requirement that the phases of translation
necessarily produce successive versions of the source code, nor that the
version of the source code that would be the output of a given phase
necessarily exist at any point. Nonetheless, in the compilers I've
looked at, the preprocessor and compiler are distinct to at least some
degree. In some cases, they're entirely separate programs, while in
others they're compiled into a single program, but still operate
separately from each other.

But the same could be said of other parts of the compiler as well.

Regards,
Bart.
 
S

Siam

While we're on the subject... I do have a question or two regarding
#defines...

1) Does the text-substitution occur across the whole file, or from the
#define onwards?

2) How / in what order does it do the substitutions? In that if I have:

#define DEF1 DEF2
#define DEF2 DEF3
#define DEF3 doStuff()

Would it do a pass for each #define, performing the substitution for
all occurences of DEF# in the file (including those in the other
#defines), remove the #define statement, then move onto the next define
statement? Or does it just do a single pass for the whole file,
performing text substitutions for the defined words only in the actual
c++ code (i.e. not performing text-substitutions for occurences within
another define statement)?

Cheers,

Siam
 
J

Jerry Coffin

Jerry Coffin wrote:


But the same could be said of other parts of the compiler as well.

Of course -- but this makes it no less true of the compiler vs.
preprocessor.
 
J

Jerry Coffin

While we're on the subject... I do have a question or two regarding
#defines...

1) Does the text-substitution occur across the whole file, or from the
#define onwards?

From the #define onwards. You can even define the same token as having
different substitutions at different points in the same file, if you
want to -- for example:

#define X Y
// ...
#undef X
#define X Z
// ...
2) How / in what order does it do the substitutions? In that if I have:

#define DEF1 DEF2
#define DEF2 DEF3
#define DEF3 doStuff()

Would it do a pass for each #define, performing the substitution for
all occurences of DEF# in the file (including those in the other
#defines), remove the #define statement, then move onto the next define
statement? Or does it just do a single pass for the whole file,
performing text substitutions for the defined words only in the actual
c++ code (i.e. not performing text-substitutions for occurences within
another define statement)?

After all parameters in the replacement list have been substituted, the
resulting preprocessing token sequence is rescanned with all subsequent
preprocessing tokens of the source file for more macro names to replace.

If the name of the macro being replaced is found during this scan of the
replacement list (not including the rest of the source file?s
preprocessing tokens), it is not replaced.

(Not my words -- that's section 16.3.4/1 and 16.3.4/2 of the standard.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,022
Latest member
MaybelleMa

Latest Threads

Top