Bug 26531 - Use of templates in macro expansion confuses pre-processor
Summary: Use of templates in macro expansion confuses pre-processor
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.2.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-03-02 18:14 UTC by Peter Schuller
Modified: 2006-03-02 18:27 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Peter Schuller 2006-03-02 18:14:47 UTC
Given the following code:

==== BEGIN CODE ====
template <typename A, typename B>
class SomeClass
{
};

#define MYMACRO(BLOCK) \
{                      \
  BLOCK                \
}                      \

int
main(void)
{
  MYMACRO({
    SomeClass<int,int> test;
  });
}
==== END CODE ====

gcc (3.3.5 on Debian sarge, 3.4.4 on FreeBSD 6.0 from base and 4.2.0 on FreeBSD frmo ports) fails to compile it, complaining that MYMACRO was given too many arguments. For example, with 4.2.0:

==== BEGIN COMPILER OUTPUT ====
% g++42 -v -save-temps -o macroarg macroarg.cc
Using built-in specs.
Target: i386-portbld-freebsd6.0
Configured with: ./..//gcc-4.2-20060218/configure --disable-nls --with-system-zlib --with-libiconv-prefix=/usr/loca
ib/gcc/i386-portbld-freebsd6.0/4.2.0/include/c++/ --infodir=/usr/local/info/gcc42 --disable-shared --disable-libgcj --prefix=/usr/local i386-portbld-freebsd6.0
Thread model: posix
gcc version 4.2.0 20060218 (experimental)
 /usr/local/libexec/gcc/i386-portbld-freebsd6.0/4.2.0/cc1plus -E -quiet -v macroarg.cc -mtune=i386 -fpch-preprocess -o macroarg.ii
ignoring nonexistent directory "/usr/local/lib/gcc/i386-portbld-freebsd6.0/4.2.0/gcc/i386-portbld-freebsd6.0/4.2.0/../../../../i386-portbld-freebsd6.0/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/lib/gcc/i386-portbld-freebsd6.0/4.2.0/include/c++/
 /usr/local/lib/gcc/i386-portbld-freebsd6.0/4.2.0/include/c++//i386-portbld-freebsd6.0
 /usr/local/lib/gcc/i386-portbld-freebsd6.0/4.2.0/include/c++//backward
 /usr/local/include
 /usr/local/lib/gcc/i386-portbld-freebsd6.0/4.2.0/gcc/i386-portbld-freebsd6.0/4.2.0/include
 /usr/include
End of search list.
macroarg.cc:16:4: error: macro "MYMACRO" passed 2 arguments, but takes just 1

==== END COMPILER OUTPUT ====

For completeness since it is asked for, following is the pre-processor file which is incomplete for obvious reasons:

=== BEGIN PRE-PROCESSOR OUTPUT ===
# 1 "macroarg.cc"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "macroarg.cc"
template <typename A, typename B>
class SomeClass
{
};






int
main(void)
{
  MYMACRO;


}
=== END PRE-PROCESSOR OUTPUT ===

It seems to be triggered when the type is parameterized on at least two types. Removing the MYMACRO({...}) wrapping makes it compile. Putting just about anything except certain template heavy stuff inside it also compiles.

(The above is obviously a contrived example to trigger the issue; my real usage is a macro for critical sections with guaranteed mutex cleanup.)
Comment 1 Andrew Pinski 2006-03-02 18:27:20 UTC
This is not a bug.
There are two arguments passed to the macro MYMACRO, "{\n    SomeClass<int" and "int> test;\n  }".
the only way to force an argument passed to the preprocessor macros is to wrap them in parentheses.