知道是否使用了const限定符

在C中是否有任何方法可以找到变量是否具有const限定符? 或者它是否存储在.rodata部分?

例如,如果我有这个function:

void foo(char* myString) {...} 

在这两个不同的函数调用中应该采取不同的操作:

 char str[] = "abc"; foo(str); foo("def"); 

在第一种情况下,我可以修改字符串,在第二种情况下没有。

不在标准C中,即不可移植。

myString只是foochar* ,所有其他信息都丢失了。 无论您输入函数的是什么,都会自动转换为char*

C不知道“ .rodata ”。

根据您的平台,您可以检查myString的地址(如果您知道地址范围)。

你不能仅仅使用这种语言来区分它们。 换句话说,如果不重复使用特定于您正在使用的编译器的function,这是不可能的,这可能不是可移植的。 但有几点重要的评论:

在第一种情况下,你可以修改字符串,但你不能。 如果您想要一个可变字符串,请使用初始化而不是赋值

 char *str1 = "abc"; // NOT OK, should be const char * const char *str2 = "abc"; // OK, but not mutable char str3[] = "abc"; // OK, using initialization, you can change its contents 
 #include void foo(char *mystr) { int a; /*code goes here*/ #ifdef CHECK int local_var; printf(" strings address %p\n",mystr); printf("local variables address %p \n",&local_var); puts(""); puts(""); #endif return; } int main() { char a[]="hello"; char *b="hello"; foo(a); foo(b); foo("hello"); } 

在使用gcc -DCHECK prog_name.c进行编译并在我的linux机器上执行以下输出时……

 strings address 0xbfdcacf6 local variables address 0xbfdcacc8 strings address 0x8048583 local variables address 0xbfdcacc8 strings address 0x8048583 local variables address 0xbfdcacc8 

对于第一种情况,当字符串被定义并以“适当的c方式为可变字符串”初始化时,地址之间的差异是0x2E。(5字节)。

在第二种情况下,当字符串被定义为char * p =“hello”时,地址的差异是0xB7D82745.Thats大于我的堆栈的大小。所以我很确定字符串不在堆栈上。这是唯一的地方你会发现它是.rodata部分。

第三个是类似的情况

PS:如上所述,这不是便携式的,但原始问题通过提及.rodata :)几乎没有任何可移植性的范围。

GCC提供__builtin_constant_p内置函数,使您可以在编译时确定表达式是否为常量:

内置函数:int __builtin_constant_p(exp)

您可以使用内置函数__builtin_constant_p来确定在编译时是否已知某个值是常量,因此GCC可以对涉及该值的表达式执行常量折叠。 函数的参数是要测试的值。 如果已知参数是编译时常量,则该函数返回整数1;如果不知道它是编译时常量,则返回0。 返回0并不表示该值不是常量,而仅仅是GCC无法certificate它是具有指定的“-O”选项值的常量。

所以我猜你应该在这种情况下将你的foo函数重写为宏:

 #define foo(x) \ (__builtin_constant_p(x) ? foo_on_const(x) : foo_on_var(x)) 

foo("abc")将扩展为foo_on_const("abc")foo(str)将扩展为foo_on_var(str)