I'm experimenting a bit with trying to build NodeJS 24.11.1 with GCC 13.4.0 on an older OS X system, mostly as a can-it-be-done project.
Regardless of the reasons, among the hurdles that could be expected is a rather surprising one that seems to raise a valid general question about C++ syntax. FWIW, this happens when compiling deps/v8/src/baseline/baseline.cc.
In the deps/v8/src/codegen/interface-descriptors.h header file, there are these 2 macros, among others (I have stripped the embedded comments because otherwise I couldn't generate the preprocessed baseline.i file):
#define DEFINE_RESULT_AND_PARAMETERS(return_count, ...) \
static constexpr int kReturnCount = return_count; \
enum ParameterIndices { \
__dummy = -1, \
##__VA_ARGS__, \
\
kParameterCount, \
kContext = kParameterCount \
};
#define DEFINE_PARAMETERS(...) DEFINE_RESULT_AND_PARAMETERS(1, ##__VA_ARGS__)
class V8_EXPORT_PRIVATE VoidDescriptor
: public StaticCallInterfaceDescriptor<VoidDescriptor> {
public:
// The void descriptor could (and indeed probably should) also be NO_CONTEXT,
// but this breaks some code assembler unittests.
INTERNAL_DESCRIPTOR()
DEFINE_PARAMETERS()
DEFINE_PARAMETER_TYPES()
DECLARE_DESCRIPTOR(VoidDescriptor)
static constexpr auto registers();
};
Note how DEFINE_PARAMETERS is called without arguments, which expands to:
static constexpr int kReturnCount = 1; enum ParameterIndices { __dummy = -1,, kParameterCount, kContext = kParameterCount };
And a compiler error that seems completely justified:
../deps/v8/src/codegen/interface-descriptors.h:662:18: error: expected identifier before ',' token
662 | ##__VA_ARGS__, \
The thing is, this particular header file code hasn't changed since Node 22.21.1 - and I have been able to do a normal build of that version with clang (16), on the same system. And with GCC 13 on a Linux host. Both of these compilers must have seen that same code - and yes, when I just take the failing compile command and execute it from the shell with clang++-16 instead of g++-13, I also get an error about that missing identifier.
What am I missing here?
##__VA_ARGS__is a non-standard GCC extension that's supposed to suppress the preceding comma if the replacement list is empty. The standard defines__VA_OPT__that can be used for that purpose. Not sure why that doesn't work in your case.-std=c++20vs.-std=gnu++20indeed explains the failure. Not the 1st thing I would have thought of since this seems something where C and C++ should agree...__VA_OPT__- yet. Are you saying I should be able to replace all##__VA_ARGS__with__VA_OPT__? If I do that blindly I get an error that__VA_OPT__ should be followed by an open parenthesis. EDIT: never mind, I hadn't read the linked discussion (oops...).__dummy = -1, ##__VA_ARGS__,->__dummy = -1 __VA_OPT__ (,) __VA_ARGS__,