2012-02-25 3 views
2

Я хочу использовать gcc для проверки времени компиляции входов функций, если компилятор знает, что они являются константами.GCC Проверка времени непрерывной работы в режиме компиляции

У меня есть решение, которое очень почти работает, и насколько я вижу, он должен работать.

Примечание: __builtin_constant_p (выражение) должно возвращать, является ли выражение, как известно, константой во время компиляции.

Предположим, что мы хотим, чтобы проверить, является ли порт < 2 при вызове UART (порт), следующий код должен работать:

#include <stdio.h> 

void _uart(int port) { 
printf("port is %d", port); 
} 

#define uart(port) \ 
static_assert(__builtin_constant_p(port)? port<2: 1, "parameter port must be < 2"); \ 
_uart(port) 

int main(void) { 
int x=1; 
uart(x); 
} 

Это работает при вызове UART(). К сожалению, он не совсем работает для непостоянного x. По какой-то причине static_assert не может справиться с тем случаем, когда x не является константой, хотя в теории __builtin_constant_p() даже не передаст ей константу. Сообщение об ошибке, которое я получаю:

c:\>gcc a.cpp -std=c++0x -Os 
a.cpp: In function 'int main()': 
a.cpp:13: error: 'x' cannot appear in a constant-expression 

Любые идеи?

+0

«По какой-то причине» заключается в том, что формальная грамматика для «постоянного выражения» не имеет правила для оператора '?', Который гласит: «Если левая сторона является ложной» во время компиляции, второй параметр не обязательно должен быть постоянным выражением ». Грамматика для «постоянного выражения» говорит: «Все компоненты (даже те, которые не используются при оценке) должны быть постоянными выражениями». Поэтому сообщение об ошибке говорит, что «не может появляться в константном выражении», а не «не может отображаться в оцениваемой части константного выражения». –

ответ

1

Вы можете попробовать трюк, используемый в ядре Linux:

What is ":-!!" in C code?

The (несколько ужасно) Linux ядра макрос менее строги, какие выражения допустимы в параметре.

+0

Это работает на C, но не на C++. – Berwyn

2

Ваш код работает с g ++ (GCC) 4.8.2.

- но не с оптимизацией, как вы правильно отметили.

Если бы мы только могли использовать

static_assert(__builtin_choose_expr(__builtin_constant_p(port), \ 
          port<2, 1), "parameter port must be < 2") 

- но, к сожалению __builtin_choose_expr конструкт в настоящее время доступен только для C.

Однако есть C++ patch, который, к сожалению, не сделал его в релиз еще ,

+1

Хммм ... вы правы, что это было выполнено, но на самом деле я этого не делал, потому что забыл добавить параметр оптимизации компилятора: теперь я добавил «-O», который прекрасно воспроизводит проблему. – Berwyn