Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linkage in C: does GCC follow the C99 spec, or do I not understand the spec?

Tags:

c

gcc

linkage

c99

I'm trying to understand the exact behavior of storage class specifiers in C99, and some GCC behavior seems not to follow the spec, unless I misunderstand the spec. From 6.2.2 (2):

Within one translation unit, each declaration of an identifier with internal linkage denotes the same object or function.

However, I tested GCC (powerpc-apple-darwin9-gcc-4.2.1) with the following program:

#include <stdio.h>
static int f() {
    static int x = 0;
    return x++;
}
static int g() {
    static int x = 0;
    return x++;
}
int main(int argc, char *argv[]) {
    printf("g() = %i\n", g());
    printf("g() = %i\n", g());
    printf("f() = %i\n", f());
    printf("f() = %i\n", f());
    return 0;
}

Compiled with -std=c99, It prints the following:

g() = 0
g() = 1
f() = 0
f() = 1

If I understand the spec correctly, it should print:

g() = 0
g() = 1
f() = 2
f() = 3

I understand why GCC would deviate from the spec here, I'm just wondering if there's a deeper explanation for this behavior.

like image 411
Dietrich Epp Avatar asked Jan 29 '10 03:01

Dietrich Epp


2 Answers

In 6.2.2 (6) it says:

The following identifiers have no linkage: [...] a block scope identifier for an object declared without the storage-class specifier extern.

The static variables are block scope identifiers for objects, and they are not declared extern. Therefore they have no linkage, especially not internal linkage.

like image 192
sth Avatar answered Sep 29 '22 16:09

sth


The next paragraph, 6.2.2/3, is important:

If the declaration of a file scope identifier for an object or a function contains the storage-class specifier static, the identifier has internal linkage.

(note the emphasized file scope identifier).

Your static variables x do not have file scope, they have block scope.

like image 41
James McNellis Avatar answered Sep 29 '22 18:09

James McNellis