2015-06-29 2 views
1

У меня есть следующее утверждение о компиляции, которое терпит неудачу, если я скомпилирую без флагов -O [1-3].Сбой компиляции не завершен без оптимизации GCC

#ifndef __compiletime_error 
#define __compiletime_error(message) 
#endif 
#ifndef __compiletime_error_fallback 
#define __compiletime_error_fallback(condition) do { } while (0) 
#endif 

#define __compiletime_assert(condition, msg, prefix, suffix)  \ 
    do {        \ 
     int __cond = !(condition);    \ 
     extern void prefix ## suffix(void) __compiletime_error(msg); \ 
     if (__cond)      \ 
      prefix ## suffix();    \ 
     __compiletime_error_fallback(__cond);   \ 
    } while (0) 

#define _compiletime_assert(condition, msg, prefix, suffix) \ 
    __compiletime_assert(condition, msg, prefix, suffix) 

#define compiletime_assert(condition, msg) \ 
    _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__) 

#endif 

Это будет сочетать с следующим макросом, который находится в другом (конкретной GCC-4) файл:

#define __compiletime_error(message) __attribute__((error(message))) 

вопрос исходит из этой строки в коде:

 extern void prefix ## suffix(void) __compiletime_error(msg); \ 

Кажется GCC не понимает extern в макросе без -O[1-3] флаг. Я не уверен, как объявить __compiletime_error, прежде чем он будет вызван в этот макрос. Если я удалю эту линию, я получаю известное предупреждение от Implicit declaration of a function

+0

Ведущие подчеркивания (ы) '_' зарезервированы для инструментальной цепочки и ее заголовков. Вы не должны использовать это для своих собственных идентификаторов. – Olaf

+0

@Olaf, вы имеете в виду, мне просто нужно переименовать '__compiletime_error()'? Я сделал это, и это ничего не меняет ... – ARH

+0

Я не сказал, что это поможет здесь. Это было общее замечание, что _might_ вызывает проблемы. Чтобы увидеть, что ват идет, проверьте вывод препроцессора (опция '-E'). – Olaf

ответ

3

Ваш фреймворк compiletime_assert полагается на оптимизатор, выполняющий удаление мертвого кода, чтобы удалить вызов prefix ## suffix. Это очень хрупко и никоим образом не гарантируется.

Вместо этого попробуйте использовать одно из решений от Ways to ASSERT expressions at build time in C - или, поскольку вы используете современный компилятор, используйте C11 _Static_assert.

Смежные вопросы