Код, работающий как C-File, но не как C ++ - Файл, Ошибка: '__builtin_types_compatible_p' не был объявлен в этой области - PullRequest
0 голосов
/ 24 октября 2019

Я закодировал макрос, где я могу использовать любое количество значений. Если это числа с плавающей точкой, они преобразуются в 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. Так что же я сделал не так?

Редактировать: Это также мой первый вопрос, поэтому любые советы о том, как задавать лучшие вопросы, приветствуются.

1 Ответ

0 голосов
/ 24 октября 2019

Из gcc docs :

Примечание: эта конструкция доступна только для C.

Для C ++ вы можете взятьПосмотрите на этот ответ:

Как определить тип аргумента в c ++

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...