Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C mutually referencing static initializers

Is it possible in C to have mutually referencing static variable initializers, as shown in the example below?

The example compiles, without warning in gcc -Wall, if line 2 is added to pre-declare "B". Line 2 is distasteful because it also defines B, as does line 4. The splint lint program, with -weak checking, warns that "B" is defined twice: "Variable B redefined. A function or variable is redefined. One of the declarations should use extern."

Typically a declaration would be made with the extern keyword, but extern and static cannot be used together, and will not compile under gcc.

#include <stdio.h>                               /*1*/
volatile static void * B;                        /*2*/
volatile static void * A = &B;                   /*3*/
volatile static void * B = &A;                   /*4*/
int main()                                       /*5*/
{                                                /*6*/
    printf("A = %x, B = %x\n", (int)A, (int)B);  /*7*/
    return 0;                                    /*8*/
}                                                /*9*/

Thank you

like image 976
a b Avatar asked Oct 02 '12 21:10

a b


2 Answers

Notwithstanding the strange placement of volatile with relation to static, the code you posted is perfectly valid C. It uses a C-specific feature called tentative definitions. This feature makes sure that you have only one B in your program: both definitions of B define the same entity. There's nothing "distasteful" about it.

The warning you get from splint is invalid. In C++ language this would indeed constitute a multiple-definition error, but not in C. The comment about extern makes no sense whatsoever within the context of C language.

like image 120
AnT Avatar answered Oct 25 '22 15:10

AnT


This is pointless.

EDIT:

Yes, there's no need in 'extern' (Thanks, AndreyT and Adam Rosenfield), but &B has a type of void**, not void*.

Of course, void** casts to void*, but what's the point? If you want aliases or pointers to each other, then just declare a third variable, "the buffer", and point to it in A and B.

unsigned char SomeBuffer[LENGTH];

void* A = SomeBuffer;
void* B = SomeBuffer;
like image 28
Viktor Latypov Avatar answered Oct 25 '22 14:10

Viktor Latypov