tags:

views:

116

answers:

3

Hi, I have the following declaration in my code:

u32 volatile __attribute__((nocast)) *A, *B;

Is this equivalent to:

u32 volatile __attribute__((nocast)) *A;
u32 volatile __attribute__((nocast)) *B;

or:

u32 volatile __attribute__((nocast)) *A;
u32 volatile                         *B;

or even:

u32 volatile __attribute__((nocast)) *A;
u32                                  *B;

A small update for this. It's linux kernel code, so the only possible compiler is gcc. I know that I'm probably going to end up writing this on multiple lines, but I am curious.

For example, in the following linux kernel code, they use it similarly to how I wanted to. Is that code buggy?


One final update, if I use the following code:

int main() {
    int __attribute__((weak)) a, b;
}

I get the following warnings under gcc:

foo.c: In function ‘main’:
foo.c:5: error: weak declaration of ‘a’ must be public
foo.c:5: error: weak declaration of ‘b’ must be public

This says to me that it's trying to apply the attribute to both variables. I'm going to run with the idea that it doesn't vary over attribute types.

+3  A: 

It depends on the compiler you're using and what __attribute__((nocast)) means to it. This isn't standard C, mind you.

In any case, it is prudent to protect yourself from the ambiguity by simply writing the declarations separately for each variable.

Eli Bendersky
+1 If there's any question as to how the code might be interpreted, simply re-write it in a non-ambiguous form.
bta
+4  A: 

volatile qualifier is a common part of the entire declaration. The * is a part of an individual declarator. So

u32 volatile *A, *B;

is equivalent to

u32 volatile *A;
u32 volatile *B;

This is what the language specification says.

However, __attribute__ is not a part of the language, meaning that you have to consult your compiler documentation to figure out how it behaves.

AndreyT
+1  A: 

~You can test it and see, but I wouldn't want to write code that depended on that. It won't be clear to other readers, you may forget which way it is, or since it is an extension anyway it could change or may be done differently by different compiler vendors that try to offer this syntax (intel's linux C/C++ compiler, llvm, and a few other compilers use this syntax that originated with GCC {I believe} ).

You should probably use a typedef or a different line for each to be clear and sure about this.

If you are working on writing another compiler and want to match the syntax with some ~standard~ your best resource is going to be asking the gcc developer list.

nategoose
I'm honestly not sure how to test it. I was looking online to try and see if I could get gcc to print out the type name as a string, but I couldn't find anything.
sharth
`u32 volatile __attribute__((nocast)) *A, *B;` `B = malloc(sizeof(double));` `double X = *(double *)B;` This code should produce a compiler error or warning if nocast is applied to B.
nategoose