I'm looking for a creative solution for making sure that variables delivered to a specific macro are declared with type volatile in C language, with TMS470 compiler. meaning:
good method:
volatile int *_p_reg;
VOLATILE_MACRO(_p_reg);
compilation failure:
int *_p_reg;
VOLATILE_MACRO(_p_reg);
I wish to perform the verification after the compilation, meaning going over the disassembly or the debug information and identify those calls. I can't seem to find any evidence for the volatile in the debug info.
any ideas?
thanks!
Two possible solutions using gcc extensions. The run-time version uses __builtin_types_compatible_p
and an assert
. The compile-time version is similar but uses a hack to get a static assert which fires at compile-time (albeit with a rather cryptic error message):
#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;
}
Note that if you need to support other volatile
types then the macro can simply be extended with multiple chained __builtin_types_compatible_p
tests, e.g.
#define VOLATILE_MACRO(p) \
assert (__builtin_types_compatible_p(typeof(p), typeof(volatile int *)) ||
__builtin_types_compatible_p(typeof(p), typeof(volatile short *)))