Is variadic macro expansion possible in GLSL? - opengl

In C99 we have variadic macro expansion via the #define XXX(...) __VA_ARGS__ syntax.
This doesn't seem to work in GLSL.
Is there a similar mechanism with different syntax? Is this implementation specific?

The GLSL specification borrows most of its preprocessor behavior from C++. Specifically, C++98. As such, it does not have variadic macros. Nor does it have anything like them.

Related

Best way to deal with namespace collision of likely/unlikely macros, with boost code

The class boost::date_time::special_values_parser has a method named likely. However, I am using this class in code that uses likely/unlikely as branch-prediction macros (see How do the likely/unlikely macros in the Linux kernel work and what is their benefit?). Is there a way to still use this code while also using the macros?
Is there a way to still use this code while also using the macros?
Yes. Function-like macros require () immediately to expand, regular functions don't. Workaround:
(boost::date_time::special_values_parser::likely)( /* ... */ );

Will the macro `assert` be removed in C++20?

According to cppreference, assert will be used as a C++ attribute.
However, there already exist tons of projects heavily dependent on the macro assert, is there any bad effect?
No. The proposal p0542r5 which introduces C++20 contracts says:
Note that while assert(expression) would expand as a function-like macro with the appropriate header, assert: is not a function-like invocation, so does not expand.
The new use of assert won't cause any problems, because it is not followed by a ( and therefore the function-style macro assert(blah) won't be invoked.

What's this ellipsis in c++ : #define MBGL_DEFINE_ENUM(T, values...)?

While trying to build mapboxgl-native with msvc 2017, I had errors with the following construct in their enum.hpp
#define MBGL_DEFINE_ENUM(T, values...)
This macro is used like this
I could not find the documentation for this c++ syntax.
Which version of c++ defines this ellipsis construct ? How is it called ?
This isn't standard C++. The standard way would not name the ellipsis. It's a GCC extension.
Variadic macros in standard C++ look somewhat like this:
#define foo(arg, ...) arg __VA_ARGS__
Where __VA_ARGS__ stands for all the arguments in the ellipsis.

Predefined macros and C++11

As far as I know predefined macros and operations like #ifdef, #define...etc are some thing related to the compiler not to the language standards.
My questions are:
Is the above true? completely true? and exceptions?
Is the following code completely C++11 valid, standard and best practice?
//Some includes here
#define CONCURRENCY
int main(){
//some code here
#ifdef CONCURRENCY
concurrency::parallel_for_each(begin(solutions), end(solutions), [&](schedule_& solution){
#else
for (auto& solution:solutions){
#endif
//Some code here
#ifdef CONCURRENCY
});
#else
}
#endif
}
EDIT:
a bit out of the scope of the question:
Is the above code the best way to give an option to compile the code with and without concurrency option ?
Your code is correct. (As far as the macro use is concerned, I didn't really "parse" the code itself.)
C preprocessor directives -- oversimplified, "the stuff that starts with #something" -- are handled before the compiler actually gets to "see" the code. (They are still part of the language standard, i.e. defined in the same paper as the language.)
As long as whatever you do with the C preprocessor results in valid code, the compiler will accept it.
There are things that do affect the compiler. #pragma, for example, introduces implementation-defined functionality. This is covered by the language standard as well.
As for "best practice", #ifdef / #else / #endif isn't the cleanest design, but sometimes it's the quickest way to solve platform specifics. As with basically everything in C/C++ (like the dreaded macros), it's OK as long as you don't overdo it. Put it in some central place (as opposed to having it spread all over your code base), and document it so that people that come after you can make sense of your #ifdef's, and perhaps replace them with a better solution.
The following preprocessor directives
#include
#define
#undef
#if
#ifdef
#ifndef
#error
have a standard behavior in C/C++.
The #pragma directive is like an exception because is make to be interpreted by compiler or other external stuff.
Your code is valid and standard in C++11, but not follow the best practices. Using preprocessor directives are not encouraged. Current efforts on the developing of C++ language aims to eliminate the need of preprocessor completely. Instead you may use other static code generation techniques like template metaprogramming.

#ifdef inside a macro call works with gcc but not with msvc [duplicate]

This question already has an answer here:
Are preprocessor directives allowed in a function-like macro's argument?
(1 answer)
Closed 5 months ago.
I am have a macro TYPELIST which takes variadic arguments. I want to have something like
typedef TYPELIST(A
,B
,C
,D
#ifdef BLA_
,E
#endif
,F)
This works perfectly with gcc. However, when I try to compile it with MSVC it parses ifdef and endif as macro arguments. I know one way would be to put the macro call inside an ifdef. However, if I have a huge list and if I want to include different classes depending on different macros defined, it would become tedious. Is there a particular reason why this works in gcc and not with MSVC?
Using #ifdef inside a macro isn't legal. I am sort of surprised that gcc allows this. I'm afraid you have to put the #ifdef around the entire definition, i.e.
#ifdef BLA_
typedef TYPELIST(a,b,c,d,e,f)
#else
typedef TYPELIST(a,b,c,d,f)
#endif
According to the standard (ยง16.3.4/3), "The resulting completely
macro-replaced preprocessing token sequence is not processed as
a preprocessing directive even if it resembles one,[...]". If
g++ processes the #ifdef/#endif here, it's an error in the
compiler (at least if you've requested standards conformance,
e.g. with -std=...).