Определить изменчивое объявление в отладочной информации / разборке
Я ищу креативное решение для обеспечения того, чтобы переменные, доставляемые конкретному макросу, объявлялись с типом volatile на языке C, с помощью компилятора TMS470. имея в виду:
хороший метод:
volatile int *_p_reg;
VOLATILE_MACRO(_p_reg);
ошибка компиляции:
int *_p_reg;
VOLATILE_MACRO(_p_reg);
Я хочу выполнить проверку после компиляции, то есть перейти к разборке или отладочной информации и идентифицировать эти вызовы. Я не могу найти никаких доказательств изменчивости в отладочной информации.
есть идеи?
Спасибо!
2 ответа
Два возможных решения с использованием расширений gcc. Во время выполнения версия использует __builtin_types_compatible_p
и assert
, Версия во время компиляции похожа, но использует хак для получения статического утверждения, которое срабатывает во время компиляции (хотя и с довольно загадочным сообщением об ошибке):
Во время выполнения
#include <stdio.h>
#include <assert.h>
#define VOLATILE_MACRO(p) \
assert (__builtin_types_compatible_p(typeof(p), typeof(volatile int *)))
int main()
{
volatile int * x;
int * y;
VOLATILE_MACRO(x); // <<< OK
VOLATILE_MACRO(y); // <<< run-time error
return 0;
}
Во время компиляции
#include <stdio.h>
#include <assert.h>
#define A BUILD_NAME(__LINE__)
#define BUILD_NAME(line) BUILD_NAME2(line)
#define BUILD_NAME2(line) assert_ ## line
#define STATIC_ASSERT(test) typedef char A[(test) ? 1 : -1]
#define VOLATILE_MACRO(p) \
STATIC_ASSERT (__builtin_types_compatible_p(typeof(p), typeof(volatile int *)))
int main()
{
volatile int * x;
int * y;
VOLATILE_MACRO(x); // <<< OK
VOLATILE_MACRO(y); // <<< compile error
return 0;
}
Обратите внимание, что если вам нужно поддерживать другие volatile
типы, то макрос может быть просто расширен с несколькими цепочками __builtin_types_compatible_p
тесты, например
#define VOLATILE_MACRO(p) \
assert (__builtin_types_compatible_p(typeof(p), typeof(volatile int *)) ||
__builtin_types_compatible_p(typeof(p), typeof(volatile short *)))
Я бы не ожидал, что таковые будут, но, конечно, дело за компилятором.
Конечно, вы можете перестроить его так, чтобы макрос выполнял полное определение, т.е.
#define VOLATILE_MACRO(t, p) volatile t p
и используйте это как:
VOLATILE_MACRO(int, _p_reg);
но, конечно, это может не сработать для вас.