Определить изменчивое объявление в отладочной информации / разборке

Я ищу креативное решение для обеспечения того, чтобы переменные, доставляемые конкретному макросу, объявлялись с типом 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);

но, конечно, это может не сработать для вас.

Другие вопросы по тегам