Error when building c code with -D - c

I get the following errors when I'm trying to build my c code files with -D. But, if I build it without -D, it works. I don't know why. Thanks. (My machine is ubuntu12.10, 32bit)
gcc c1.c c2.c -D DEBUG
/tmp/ccX04EIf.o:(.data+0x0): multiple definition of `g'
/tmp/cc0j9MoU.o:(.data+0x0): first defined here
collect2: ld returned 1 exit status
Here is my source code:
global.h
#ifdef DEBUG
int g = 23;
static int init = 1;
#else
int g;
static int init = 0;
#endif
c1.c
#include "global.h"
int f() {
return g + 1;
}
c2.c
#include <stdio.h>
#include "global.h"
int main() {
if (!init) {
g = 37;
}
int t = f();
printf("calling f yields %d\n", t);
return 0;
}

You define the variable g in the header file, that means it will be defined in all source files that includes the header file.
Instead declare it, like
extern int g;
and then define it in a single source file.

The difference between the two code paths (with and without DEBUG) is the initialization of the g variable. Without it, it is only a "tentative" definition, and so the symbol is only generated in the file that really uses it, namely c2.o.
With initialization it is a real definition of the symbol, and so it is also generated in c1.o.
As a rule of thumb, header files should never contain data definitions, only declarations. Data "declarations-only" should be made with the keyword extern. You'd then need to define any such symbol in exactly one of your .c files.

Related

Use of modifier static in c

I'm a beginner learning c. I know that use of word "static" makes a c function and variable local to the source file it's declared in. But consider the following...
test.h
static int n = 2;
static void f(){
printf("%d", n);
}
main.c
#include <stdio.h>
#include "test.h"
int main()
{
printf("%d", n);
f();
return 0;
}
My expected result was that an error message will throw up, since the function f and variable n is local to test.h only? Thanks.
But instead, the output was
2
2
EDIT:
If it only works for a compilation unit, what does that mean? And how do I use static the way I intended to?
static makes your function/variable local to the compilation unit, ie the whole set of source code that is read when you compile a single .c file.
#includeing a .h file is a bit like copy/paste-ing the content of this header file in your .c file. Thus, n and f in your example are considered local to your main.c compilation unit.
Example
module.h
#ifndef MODULE_H
#define MODULE_H
int fnct(void);
#endif /* MODULE_H */
module.c
#include "module.h"
static
int
detail(void)
{
return 2;
}
int
fnct(void)
{
return 3+detail();
}
main.c
#include <stdio.h>
#include "module.h"
int
main(void)
{
printf("fnct() gives %d\n", fnct());
/* printf("detail() gives %d\n", detail()); */
/* detail cannot be called because:
. it was not declared
(rejected at compilation, or at least a warning)
. even if it were, it is static to the module.c compilation unit
(rejected at link)
*/
return 0;
}
build (compile each .c then link)
gcc -c module.c
gcc -c main.c
gcc -o prog module.o main.o
You have included test.h in main.c.
Therefore static int n and static void f() will be visible inside main.c also.
When a variable or function is declared at file scope (not inside any other { } brace pair), and they are declared static, they are local to the translation unit they reside in.
Translation unit is a formal term in C and it's slightly different from a file. A translation unit is a single c file and all the h files it includes.
So in your case, the static variable is local to the translation unit consisting of test.h and main.c. You will be able to access it in main.c, but not in foo.c.
Meaning that if you have another .c file including test.h, you'll get two instances of the same variable, with the same name. That in turn can lead to all manner of crazy bugs.
This is one of many reasons why we never define variables inside header files.
(To avoid spaghetti program design, we should not declare variables in headers either, unless they are const qualified.)

C - usage of extern qualifier

I have following three files. In the header file, I declare a global variable and tried to access it other files using extern. But I got the linker errors.
Header1.h
#ifndef HEADER1_H
#define HEADER1_H
#include<stdio.h>
int g = 10;
void test();
#endif
test.c
#include "header1.h"
extern int g;
void test()
{
printf("from print function g=%d\n", g);
}
main.c
#include "header1.h"
extern int g;
int main()
{
printf("Hello World g=%d\n", g);
test();
getchar();
return 0;
}
Linker error:
LNK2005 "int g" (?g##3HA) already defined in main.obj
LNK1169 one or more multiply defined symbols found
My understanding about extern is that a variable can be defined only once but can be declared multiple times. I think I follow it this way - I defined the global variable g in the header file and tried to access it in the .c files.
Could you please correct my understanding? What actually causes the linker error here? I did not define g multiple times.
You get a multiple definition error because you put the definition in the header file. Because both source files include the header file, that results in g being defined in both places, hence the error.
You want to put the declaration in the header file and the definition in one source file:
In header1.h:
extern int g;
In test.c:
int g = 10;
And nothing in main.c.

What is C Header Linguistically?

I need to know what is meant by "Header" in C language? is it:
an area in the code, like header area in HTML code (a title> or declaration area? or definition area?, or kind of)?
or it is like a function (can be: function, or sub routine, or a scope, or kind of) that can be called.
A header is a convention generally accepted by C programmers.
It is a usually a .h file which is included into C source files which provides several benefits.
1.- Provides declaration of data types, global variables, constants and functions.
So you don't have to rewrite them time and again. And if they need being changed you just need to change it in a single file.
In example this program composed of two compliation units (two .c files) compiles and runs just fine.
// File funcs.c
#include <stdio.h>
struct Position {
int x;
int y;
};
void print( struct Position p ) {
printf("%d,%d\n", p.x, p.y );
}
// File main.c
struct Position {
int x;
int y;
};
int main(void) {
struct Position p;
p.x = 1; p.y = 2;
print(p);
}
But it is more mantainable to have the declaration for the struct Position in a header file and just #include it everywhere it is needed, like this :
// File funcs.h
#ifndef FUNCS_H
#define FUNCS_H
struct Position {
int x;
int y;
};
#endif // FUNCS_H
//File funcs.c
#include <stdio.h>
#include "funcs.h"
void print( struct Position p ) {
printf("%d,%d\n", p.x, p.y );
}
//File main.c
#include "funcs.h"
int main(void) {
struct Position p;
p.x = 1; p.y = 2;
print(p);
2.- Provides some type safety.
C features implicit declaration of functions. A "feature" (or rather an arguable language design mistake) which was fixed in C99.
Consider this program composed of two .c files :
//File funcs.c
#include<stdio.h>
int f(long n)
{
n = n+1;
printf("%ld\n", n );
}
// File main.c
int main(void)
{
f("a");
return 0;
}
With gcc this program compiles without warnings or errors. But does not behave as we could reasonable expect and desire :
jose#cpu ~/t/tt $ gcc -o test *.c
jose#cpu ~/t/tt $ ./test
4195930
Using a header file like this :
//File funcs.h
#ifndef FUNCS_H
#define FUNCS_H
int f(long n);
#endif // FUNCS_H
//File funcs.c
#include<stdio.h>
int f(long n) {
n = n+1;
printf("%ld\n", n );
}
// File main.c
#include"funcs.h"
int main(void) {
f("a");
return 0;
}
The program still compiles and works wrong but at least we get a warning :
jose#cpu ~/t $ gcc -o test *.c
main.c: In function 'main':
main.c:5:5: warning: passing argument 1 of 'f' makes integer from pointer without a cast
f("a");
^
In file included from main.c:2:0:
funcs.h:3:5: note: expected 'long int' but argument is of type 'char *'
int f(long n);
^
jose#cpu ~/t $ ./test
4195930
3.- Provide a public interface while letting the implementation details remain hidden.
When you design your program it is desirable to make it modular. That is to ensure that different parts of it (modules) are as independient as possible. So that when you need to make a change to one module you need not be worried about such change affecting other modules
Headers help in doing this because you put in the header of a modules the data structures, function prototypes and constants that will be needed by the users of such module.
The implementation details go into .c files.
That is how libraries work. The API interface is specified and distributed in header files. But the API code is in .c files which don't need to be distributed. As an user of the library you just need the headers and the compiled library, not its source code.
What is C header Linguistically?
Referring linguistically I'd say a C header file describes the interface as provided by a translation unit, namely the accompanying C file.
"interface" by means of
types
constants
(global) variables
functions
Not all of the above need to be part of a C header.
C headers are optional from the C language's perspective, but by convention they are expected to exist.
a header is a file with the .h extension.
It is meant to help the compiler to understand the symbol (method, function, struct, variable...) that are used within the code. See of it like an glossary at the end of a book.
It is used solely for development purpose.
It helps develloper knowing what function are available without having to look in all the implementation file. Like a man page.
A search on google? http://www.tutorialspoint.com/cprogramming/c_header_files.htm :)
Usually when talking about "headers" in C, what is meant is the files you include with the #include preprocessor directive. Those are called header files.
It could also be other things, like a comment at the top of a source (or header file) could be header. A comment before a function could be a function header.
Or when reading data files or data over the internet, many protocols have the data split into a header and the actual data (see e.g. HTTP).

Static constants

Does it make any difference in C99 when one writes const int x = 1; vs. static const int x = 1; in a header (*.h) file?
Yes. First, I don't advise you to place such definitions in a header file, but if you do then it depends on where the header file is included. Anyway, static makes the variable local to the current program unit. Here is an example:
mp1.c:
#include <stdio.h>
void myfunc(void);
const int x = 1;
int main (int argc, char *argv[])
{
printf ("main: value of x: %d\n",x);
myfunc();
return 0;
}
mp2.c:
#include <stdio.h>
extern int x;
void myfunc(void)
{
printf ("myfunc: value of x: %d\n",x);
}
compilation:
gcc -o mp mp1.c mp2.c
works fine. Now change mp1.c to use static const int x = 1; and when we compile (actually its a link error), we get:
home/user1> gcc -o mp mp1.c mp2.c
/tmp/ccAeAmzp.o: In function `myfunc':
mp2.c:(.text+0x7): undefined reference to `x'
collect2: ld returned 1 exit status
The variable x is not visible outside of mp1.c.
The same applies to the static prefix to functions.
As cdarke said, it makes a difference.
const int x = 1; creates a for the linker visible symbol, for each module including your h-file.
The linker should stop then with an error, as there are multiple (visible) defines of the same symbol.
static const int x = 1; creates a variable but no linker symbol, for each module including your h-file.
The linker could link the code, but as you created multiple instances of the variable with the same name, it's not sure that your code works as expected.
Btw. It's an absolutly bad idea to define a variable in a h-file, the standard way is to define them in the c-file and only to declare them in the h-file (if you really need to access them).
You use static when you only want to use the variable in one module, and it should be invisible to all others.
const ... only if you really need to access it from another module, but IMHO you should normally avoid global accessible variables.
myFile.c
#include "myFile.h"
const int x=1;
static const int y=2;
myFile.h
extern const int x;

Duplicate symbol in C using Clang

I am currently working on my first "serious" C project, a 16-bit vm. When I split up the files form one big source file into multiple source files, the linker (whether invoked through clang, gcc, cc, or ld) spits out a the error:
ld: duplicate symbol _registers in register.o and main.o for inferred
architecture x86_64
There is no declaration of registers anywhere in the main file. It is a uint16_t array if that helps. I am on Mac OS 10.7.3 using the built in compilers (not GNU gcc). Any help?
It sounds like you've defined a variable in a header then included that in two different source files.
First you have to understand the distinction between declaring something (declaring that it exists somewhere) and defining it (actually creating it). Let's say you have the following files:
header.h:
void printIt(void); // a declaration.
int xyzzy; // a definition.
main.c:
#include "header.h"
int main (void) {
xyzzy = 42;
printIt();
return 0;
}
other.c:
#include <stdio.h>
#include "header.h"
void printIt (void) { // a definition.
printf ("%d\n", xyzzy);
}
When you compile the C programs, each of the resultant object files will get a variable called xyzzy since you effectively defined it in both by including the header. That means when the linker tries to combine the two objects, it runs into a problem with multiple definitions.
The solution is to declare things in header files and define them in C files, such as with:
header.h:
void printIt(void); // a declaration.
extern int xyzzy; // a declaration.
main.c:
#include "header.h"
int xyzzy; // a definition.
int main (void) {
xyzzy = 42;
printIt();
return 0;
}
other.c:
#include <stdio.h>
#include "header.h"
void printIt (void) { // a definition.
printf ("%d\n", xyzzy);
}
That way, other.c knows that xyzzy exists, but only main.c creates it.

Resources