confused on basic c concept

I have the following code
foo.c
1
2
3
4
5
#include <stdio.h>
int c;
void printc(){
    printf("c is %d\n",c);
}

bar.c
1
2
3
4
5
#include <stdio.h>
int c;
void printd(){
    printf("c is %d\n",c);
}

main.c
1
2
3
4
5
6
7
int c;

int main(){
    c=4;
    printc();
    printd();
}

I compiled it with
gcc foo.c bar.c main.c

The output is
c is 4
c is 4

My questions:
1. Shouldn't it generate multi-definition error for the global variables?
2. Don't I need to include the declarations of printc and printd in the main.c file?
1.) They *should* but maybe your compiler is assuming extern on two of them...
2.) Yes, the compiler shouldn't know they exist but...

It seems like you are using a old C standard that allows these kinds of things (implicit int functions, etc)
Make sure you are using C99 preferably (C89 is also sometimes used)
For gcc use -std=c99 to force it to be c99
Do you have a book? You need to read about scope and linkage. c is defined with internal linkage and global scope. Therefore bar, foo, and main each have a completely separate c variable that is global for the functions within those files. If c had been defined within header files then you might have problems from one file including the header of another.

Are you saying that main didn't include the header files of bar and foo? Did main not include any headers?
Thanks guys for your input.
@firedraco
gcc -std=c99 generated warnings of implicit declaration of those two functions.
@kempofighter
If they are separate c variables like your said, why the assignment of c in main.c effects the c's in the other two files?
According to my c book they should all be internal to each file (based on what you posted) but that seems to conflict with your output as well as with what firedraco says. If they are all internal then your printc,printd functions should be printing values from uninitialized variables which could result in anything. Try setting c within bar and foo and see what happens. Set all 3 c's to different values.

I guess you could go find a copy of the C std and see what it indicates. Perhaps my book is wrong. I do not think that the compiler should be assuming external linkage otherwise it would be impossible to take advantage of internal linkage. You ought to be able to define variables within different files that are only internal to the files.
Last edited on
If set c to some value, it generates multi-definition error.
Here is the output of gcc -v
Using built-in specs.
Target: i486-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.4.1-4ubuntu9' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --program-suffix=-4.4 --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-targets=all --disable-werror --with-arch-32=i486 --with-tune=generic --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu
Thread model: posix
gcc version 4.4.1 (Ubuntu 4.4.1-4ubuntu9)
Okay eventually I found this statement in the book. "An ordinary external variable has external linkage but a static external variable has internal linkage". That is about as asanine of a statement as I have ever seen.

If you give different initial values to each of the three variables then you will get a linker error as you expect. Evidently in C global variables are external by default and specifying "extern" is optional. making the global static makes it have internal linkage so that you can have variables of the same name in different files which are completely different.
Last edited on
Thanks for the clarification.
Topic archived. No new replies allowed.