Know if const qualifier is used

后端 未结 4 1604
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-01-19 13:46

Is there any way in C to find if a variable has the const qualifier? Or if it\'s stored in the .rodata section?

For example, if I have this function:



        
相关标签:
4条回答
  • 2021-01-19 14:20

    You can't differ them using the language alone. In other words, this is not possible without recurring to features specific to the compiler you're using, which is likely not to be portable. A few important remarks though:

    In the first case you COULD modify the string, but you MUST NOT. If you want a mutable string, use initialization instead of assignment.

    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
    
    0 讨论(0)
  • 2021-01-19 14:21
    #include<stdio.h>
    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");
    }
    

    On compiling with gcc -DCHECK prog_name.c and executing on my linux machine the following output comes...

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

    for first case when string is defined and initialized in the "proper c way for mutable strings" the difference between the addresses is 0x2E.(5 bytes).

    in the second case when string is defined as char *p="hello" the differences in addresses is 0xB7D82745.Thats bigger than the size of my stack.so i am pretty sure the string is not on the stack.Hence the only place where you can find it is .rodata section.

    The third one is similar case

    PS:As mentioned above this isn't portable but the original question hardly leaves any scope for portability by mentioning .rodata :)

    0 讨论(0)
  • 2021-01-19 14:22

    GCC provides the __builtin_constant_p builtin function, which enables you to determine whether an expression is constant or not at compile-time:

    Built-in Function: int __builtin_constant_p (exp)

    You can use the built-in function __builtin_constant_p to determine if a value is known to be constant at compile-time and hence that GCC can perform constant-folding on expressions involving that value. The argument of the function is the value to test. The function returns the integer 1 if the argument is known to be a compile-time constant and 0 if it is not known to be a compile-time constant. A return of 0 does not indicate that the value is not a constant, but merely that GCC cannot prove it is a constant with the specified value of the `-O' option.

    So I guess you should rewrite your foo function as a macro in such a case:

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

    foo("abc") would expand to foo_on_const("abc") and foo(str) would expand to foo_on_var(str).

    0 讨论(0)
  • 2021-01-19 14:24

    Not in standard C, i.e. not portably.

    myString is just a char* in foo, all other information is lost. Whatever you feed into the function is automatically converted to char*.

    And C does not know about ".rodata".

    Depending on your platform you could check the address in myString (if you know your address ranges).

    0 讨论(0)
提交回复
热议问题