Я закодировал макрос, где я могу использовать любое количество значений. Если это числа с плавающей точкой, они преобразуются в uint_32, и позже все значения используются в методе examplefff, где я использую varargs для получения всех значений. Если я сохраню свой следующий код в C-файле, компилятор не выдаст мне ошибок, и код сработает. Если я использую этот макрос в файле c ++, он больше не работает. Вот мой код:
// Example program
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#define IS_FLOAT(x) (__builtin_types_compatible_p(typeof(x&), float))
#define CONVERT_F(x) (IS_FLOAT(x)?TRACE_FLOAT(x): (uint32_t)(x))
#define NUMARGS(...) (sizeof((int[]){__VA_ARGS__})/sizeof(int))
// Make a FOREACH macro
#define FE_1(WHAT, X) WHAT(X)
#define FE_2(WHAT, X, ...) WHAT(X),FE_1(WHAT, __VA_ARGS__)
#define FE_3(WHAT, X, ...) WHAT(X),FE_2(WHAT, __VA_ARGS__)
#define FE_4(WHAT, X, ...) WHAT(X),FE_3(WHAT, __VA_ARGS__)
#define FE_5(WHAT, X, ...) WHAT(X),FE_4(WHAT, __VA_ARGS__)
#define FE_6(WHAT, X, ...) WHAT(X),FE_5(WHAT, __VA_ARGS__)
//... repeat as needed
#define GET_MACRO(_1,_2,_3,_4,_5,_6,NAME,...) NAME
#define FOR_EACH(action,...) \
GET_MACRO(__VA_ARGS__,FE_6,FE_5,FE_4,FE_3,FE_2,FE_1)(action,__VA_ARGS__)
#define NUM_ARGS(...) GET_MACRO(__VA_ARGS__,6,5,4,3,2,1)
#define EXAMPLE1(...) EXAMPLE2(NUMARGS(__VA_ARGS__), __VA_ARGS__)
#define EXAMPLE2(size, ...) (examplefff(size, FOR_EACH(CONVERT_F, __VA_ARGS__)))
static inline uint32_t TRACE_FLOAT (float f) {
union { uint32_t u; float f; } u;
u.f = f;
return u.u;
}
void examplefff(int numArgs, ...)
{
printf("n:%u\n", numArgs);
va_list args;
va_start(args, numArgs);
for(int i=0; i<numArgs; i++)
{
uint64_t test32 = va_arg(args, uint32_t);
printf("%u\n", test32);
}
va_end(args);
}
int main()
{
EXAMPLE1(456456,3244);
}
Когда я компилирую этот файл как c-файл, компилятор не выдаёт мне никаких ошибок. Когда я компилирую это как файл c ++ (который мне нужен), я получаю следующий вывод от компилятора:
x86-gcc_6.3.0\bin\gcc testfile.cpp -Wall -std=gnu99 -O2 -o test.exe
cc1plus.exe: warning: command line option '-std=gnu99' is valid for C/ObjC but not for C++
testfile.cpp: In function 'void examplefff(int, ...)':
testfile.cpp:46:28: warning: format '%u' expects argument of type 'unsigned int', but argument 2 has type 'uint64_t {aka long long unsigned int}' [-Wformat=]
printf("%u\n", test32);
^
testfile.cpp: In function 'int main()':
testfile.cpp:6:51: error: expected primary-expression before 'typeof'
#define IS_FLOAT(x) (__builtin_types_compatible_p(typeof(x&), float))
^
testfile.cpp:7:23: note: in expansion of macro 'IS_FLOAT'
#define CONVERT_F(x) (IS_FLOAT(x)?TRACE_FLOAT(x): (uint32_t)(x))
^~~~~~~~
testfile.cpp:12:28: note: in expansion of macro 'CONVERT_F'
#define FE_2(WHAT, X, ...) WHAT(X),FE_1(WHAT, __VA_ARGS__)
^~~~
testfile.cpp:19:47: note: in expansion of macro 'FE_2'
#define GET_MACRO(_1,_2,_3,_4,_5,_6,NAME,...) NAME
^~~~
testfile.cpp:27:47: note: in expansion of macro 'FOR_EACH'
#define EXAMPLE2(size, ...) (examplefff(size, FOR_EACH(CONVERT_F, __VA_ARGS__)))
^~~~~~~~
testfile.cpp:25:23: note: in expansion of macro 'EXAMPLE2'
#define EXAMPLE1(...) EXAMPLE2(NUMARGS(__VA_ARGS__), __VA_ARGS__)
^~~~~~~~
testfile.cpp:53:3: note: in expansion of macro 'EXAMPLE1'
EXAMPLE1(456456,3244);
^~~~~~~~
testfile.cpp:6:63: error: expected primary-expression before 'float'
#define IS_FLOAT(x) (__builtin_types_compatible_p(typeof(x&), float))
^
testfile.cpp:7:23: note: in expansion of macro 'IS_FLOAT'
#define CONVERT_F(x) (IS_FLOAT(x)?TRACE_FLOAT(x): (uint32_t)(x))
^~~~~~~~
testfile.cpp:12:28: note: in expansion of macro 'CONVERT_F'
#define FE_2(WHAT, X, ...) WHAT(X),FE_1(WHAT, __VA_ARGS__)
^~~~
testfile.cpp:19:47: note: in expansion of macro 'FE_2'
#define GET_MACRO(_1,_2,_3,_4,_5,_6,NAME,...) NAME
^~~~
testfile.cpp:27:47: note: in expansion of macro 'FOR_EACH'
#define EXAMPLE2(size, ...) (examplefff(size, FOR_EACH(CONVERT_F, __VA_ARGS__)))
^~~~~~~~
testfile.cpp:25:23: note: in expansion of macro 'EXAMPLE2'
#define EXAMPLE1(...) EXAMPLE2(NUMARGS(__VA_ARGS__), __VA_ARGS__)
^~~~~~~~
testfile.cpp:53:3: note: in expansion of macro 'EXAMPLE1'
EXAMPLE1(456456,3244);
^~~~~~~~
testfile.cpp:6:68: error: '__builtin_types_compatible_p' was not declared in this scope
#define IS_FLOAT(x) (__builtin_types_compatible_p(typeof(x&), float))
^
testfile.cpp:7:23: note: in expansion of macro 'IS_FLOAT'
#define CONVERT_F(x) (IS_FLOAT(x)?TRACE_FLOAT(x): (uint32_t)(x))
^~~~~~~~
testfile.cpp:12:28: note: in expansion of macro 'CONVERT_F'
#define FE_2(WHAT, X, ...) WHAT(X),FE_1(WHAT, __VA_ARGS__)
^~~~
testfile.cpp:19:47: note: in expansion of macro 'FE_2'
#define GET_MACRO(_1,_2,_3,_4,_5,_6,NAME,...) NAME
^~~~
testfile.cpp:27:47: note: in expansion of macro 'FOR_EACH'
#define EXAMPLE2(size, ...) (examplefff(size, FOR_EACH(CONVERT_F, __VA_ARGS__)))
^~~~~~~~
testfile.cpp:25:23: note: in expansion of macro 'EXAMPLE2'
#define EXAMPLE1(...) EXAMPLE2(NUMARGS(__VA_ARGS__), __VA_ARGS__)
^~~~~~~~
testfile.cpp:53:3: note: in expansion of macro 'EXAMPLE1'
EXAMPLE1(456456,3244);
^~~~~~~~
testfile.cpp:6:51: error: expected primary-expression before 'typeof'
#define IS_FLOAT(x) (__builtin_types_compatible_p(typeof(x&), float))
^
testfile.cpp:7:23: note: in expansion of macro 'IS_FLOAT'
#define CONVERT_F(x) (IS_FLOAT(x)?TRACE_FLOAT(x): (uint32_t)(x))
^~~~~~~~
testfile.cpp:11:23: note: in expansion of macro 'CONVERT_F'
#define FE_1(WHAT, X) WHAT(X)
^~~~
testfile.cpp:12:36: note: in expansion of macro 'FE_1'
#define FE_2(WHAT, X, ...) WHAT(X),FE_1(WHAT, __VA_ARGS__)
^~~~
testfile.cpp:19:47: note: in expansion of macro 'FE_2'
#define GET_MACRO(_1,_2,_3,_4,_5,_6,NAME,...) NAME
^~~~
testfile.cpp:27:47: note: in expansion of macro 'FOR_EACH'
#define EXAMPLE2(size, ...) (examplefff(size, FOR_EACH(CONVERT_F, __VA_ARGS__)))
^~~~~~~~
testfile.cpp:25:23: note: in expansion of macro 'EXAMPLE2'
#define EXAMPLE1(...) EXAMPLE2(NUMARGS(__VA_ARGS__), __VA_ARGS__)
^~~~~~~~
testfile.cpp:53:3: note: in expansion of macro 'EXAMPLE1'
EXAMPLE1(456456,3244);
^~~~~~~~
testfile.cpp:6:63: error: expected primary-expression before 'float'
#define IS_FLOAT(x) (__builtin_types_compatible_p(typeof(x&), float))
^
testfile.cpp:7:23: note: in expansion of macro 'IS_FLOAT'
#define CONVERT_F(x) (IS_FLOAT(x)?TRACE_FLOAT(x): (uint32_t)(x))
^~~~~~~~
testfile.cpp:11:23: note: in expansion of macro 'CONVERT_F'
#define FE_1(WHAT, X) WHAT(X)
^~~~
testfile.cpp:12:36: note: in expansion of macro 'FE_1'
#define FE_2(WHAT, X, ...) WHAT(X),FE_1(WHAT, __VA_ARGS__)
^~~~
testfile.cpp:19:47: note: in expansion of macro 'FE_2'
#define GET_MACRO(_1,_2,_3,_4,_5,_6,NAME,...) NAME
^~~~
testfile.cpp:27:47: note: in expansion of macro 'FOR_EACH'
#define EXAMPLE2(size, ...) (examplefff(size, FOR_EACH(CONVERT_F, __VA_ARGS__)))
^~~~~~~~
testfile.cpp:25:23: note: in expansion of macro 'EXAMPLE2'
#define EXAMPLE1(...) EXAMPLE2(NUMARGS(__VA_ARGS__), __VA_ARGS__)
^~~~~~~~
testfile.cpp:53:3: note: in expansion of macro 'EXAMPLE1'
EXAMPLE1(456456,3244);
^~~~~~~~
Я хочу использовать макрос EXAMPLE в C-файлах и C ++ - Files. Так что же я сделал не так?
Редактировать: Это также мой первый вопрос, поэтому любые советы о том, как задавать лучшие вопросы, приветствуются.