473,385 Members | 1,356 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

Compilation error - Most likely embarassingly easy, but I can't find what's wrong.

Hi,

previously I used Eclipse CDT for compiling my files just to get
started with C and leave C++ behind. Now it's time to get a little more
serious so I've moved my files to a new workplace and begun to use GNU
Autotools. I'm sorry to say I'm new to gcc as well :(

Now I get the most ridiculous compile error which I'm unable to solve.
Can someone, please, help me with this? gcc output together with the
files mentioned in the gcc error output follows below. It is about 50
lines all in all, so I'm sure someone out there can find what's wrong
pretty quickly.

Thanks in advance anyone!
Sune

**************** Here is the gcc output *************
[sune@localhost rsd2]$ make all
make all-recursive
make[1]: Entering directory `/home/sune/gnu-ws/rsd2'
Making all in collections
make[2]: Entering directory `/home/sune/gnu-ws/rsd2/collections'
gcc -g -O2 -o collections_test DynamicString.o test_main.o
test_main.o(.rodata+0x0): In function `t1':
/home/sune/gnu-ws/rsd2/collections/test_main.c:12: multiple definition
of `DynamicString_SUCCESS'
DynamicString.o(.rodata+0x0):/home/sune/gnu-ws/rsd2/collections/DynamicString.c:10:
first defined here
test_main.o(.rodata+0x4): In function `t1':
/home/sune/gnu-ws/rsd2/collections/test_main.c:12: multiple definition
of `DynamicString_ERROR'
DynamicString.o(.rodata+0x4):/home/sune/gnu-ws/rsd2/collections/DynamicString.c:10:
first defined here
collect2: ld returned 1 exit status
make[2]: *** [collections_test] Error 1
make[2]: Leaving directory `/home/sune/gnu-ws/rsd2/collections'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/home/sune/gnu-ws/rsd2'
make: *** [all] Error 2

**************** Here is the beginning of my DynamicString.c file
*************
#include <string.h>
#include <stdlib.h>
#include <assert.h>

#include "DynamicString.h"

static const int FILE_ID = 0;

inline void DynamicString_init( DynamicString* string_obj, int trace_id
)
{
string_obj->stack_string[0] = '\0';
string_obj->heap_string = 0;
string_obj->string = 0;
string_obj->size = 0;
string_obj->capacity = DynamicString_stack_string_size;

}

**************** Here is the beginning of my DynamicString.h file
*************
#ifndef DYNAMICSTRING_H_
#define DYNAMICSTRING_H_

#include <stddef.h>

#include "../config.h" // Don't worry about the relative path, I'll
fix it...

const int DynamicString_ERROR=0;
const int DynamicString_SUCCESS=1;
enum { DynamicString_stack_string_size = 256 };

typedef struct DynamicString_
{
char stack_string[ DynamicString_stack_string_size ];
char* heap_string;
char* string;
size_t size;
size_t capacity;
} DynamicString;

**************** Here is the beginning of my test_main.c file
*************
#include <stdio.h>
#include <string.h>

#include "debug/Debug.h"
#include "collections/DynamicString.h"

int
t1(int),t2(int),t3(int),t4(int),t5(int),t6(int),t7 (int),t8(int),t9(int),t10(int);
int (*func[])(int) = { t1,t2,t3,t4,t5,t6,t7,t8,t9,t10 };

// Init
int t1( int trace_id )
{
DynamicString string;
DynamicString_init( &string, trace_id );
return 1; // Can't fail!
}

Nov 15 '05 #1
10 2325
Sune wrote:
Debug.h
What's that?
int
t1(int),t2(int),t3(int),t4(int),t5(int),
t6(int),t7(int),t8(int),t9(int),t10(int);


What's that supposed to be?
It looks like an attempt at plural prototypes (no such thing).

--
pete
Nov 15 '05 #2
pete <pf*****@mindspring.com> writes:
Sune wrote:

[...]
int
t1(int),t2(int),t3(int),t4(int),t5(int),
t6(int),t7(int),t8(int),t9(int),t10(int);


What's that supposed to be?
It looks like an attempt at plural prototypes (no such thing).


Actually, I think it's legal.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 15 '05 #3
Hi,

yes, it's legal. Maybe it looks strange because of the odd linefeeds
added by Google.

BRs
/Sune

Nov 15 '05 #4
Sune wrote:
test_main.o(.rodata+0x0): In function `t1':
/home/sune/gnu-ws/rsd2/collections/test_main.c:12: multiple definition
of `DynamicString_SUCCESS'
This is the kind of error one gets from defining objects in header files.

**************** Here is the beginning of my DynamicString.h file
*************
#ifndef DYNAMICSTRING_H_
#define DYNAMICSTRING_H_

#include <stddef.h>

#include "../config.h" // Don't worry about the relative path, I'll
fix it...

const int DynamicString_ERROR=0;
const int DynamicString_SUCCESS=1;


If you must have these in your header, you could
#define DynamicString_ERROR 0
#define DynamicString_SUCCESS 1

Or, if you have an allergy to #defines (get over it), you might try
enum {DynamicString_ERROR, DynamicString_SUCCESS};

Or, if you positively insist on defining objects in your header,
contrary to all common sense, add the 'static' qualifier.
static const int DynamicString_ERROR=0;
static const int DynamicString_SUCCESS=1;
Nov 15 '05 #5
Hi,

thanks, that was the problem.

I want to have them (DynamicString_ERROR and DynamicString_SUCCESS) in
my header accessible to clients so that clients of DynamicString can
use them to test the outcome of a call to functions I didn't include in
the code I pasted into my post.

What would be a more proper way of doing this? (Just beginning to get
into C you know)

Thanks again
/Sune

Nov 15 '05 #6
Keith Thompson wrote:

pete <pf*****@mindspring.com> writes:
Sune wrote:

[...]
int
t1(int),t2(int),t3(int),t4(int),t5(int),
t6(int),t7(int),t8(int),t9(int),t10(int);


What's that supposed to be?
It looks like an attempt at plural prototypes (no such thing).


Actually, I think it's legal.


That's a new one on me.
Thank you.

--
pete
Nov 15 '05 #7

Sune wrote:
test_main.o(.rodata+0x0): In function `t1':
/home/sune/gnu-ws/rsd2/collections/test_main.c:12: multiple definition
of `DynamicString_SUCCESS'
DynamicString.o(.rodata+0x0):/home/sune/gnu-ws/rsd2/collections/DynamicString.c:10:
first defined here
What this is saying is that it has found two objects, one in the
compilation unit it calls DynamicString.o, and one in test_main.o which
have the same name DynamicString_SUCCESS, and both visible externally!
So, it is confused ... (similar error with DynamicString_Error later).
**************** Here is the beginning of my DynamicString.h file
*************
#ifndef DYNAMICSTRING_H_
#define DYNAMICSTRING_H_
Okay this ensures that the contents are not included twice in any one
compilation unit. That is irrelevant when compiling separate
compilation units (gcc interprets each top level .c file, i.e. the ones
on the command line, as a separate compilation unit).
const int DynamicString_ERROR=0;
const int DynamicString_SUCCESS=1;
Now, these are declaring two variables DynamicString_ERROR and
DynamicString_SUCCESS outside any functions (assuming the .h file is
included outside any functions as you showed in the portion I deleted).
Such declarations, by default, declare entities with external linkage:
i.e. specify that all such entities (i.e. all entities with external
linkage everywhere in the program, not only in the compilation unit)
with the same name should refer to the same entity. So, they have the
same type, address etc., and changing the value of any of them (if they
can be changed) should change all with the same name. The compiler is
not required to check that you do not violate this, but as you saw, it
certainly can.

However, they have been initialized: this changes them from mere
declarations into definitions! Which means, you are instructing the
compiler to actual create such objects in the compilation unit.

So, now, when you include this in multiple compilation units, what is
the compiler supposed to do? The external linkage is forcing the
interpretation that there should only be one entity with each name,
whereas the definition is forcing one object per compilation unit in
which the inclusion takes place.

So, what options do you have other than having only one compilation
unit? Well, here are a few:

a) Use #define instead of an object. This just defines a new
preprocessor token which behaves identically to the number in the
compilation stage. So, it is not scoped (well, you are at global
scope, so that is not terribly important, except you cannot hide it by
local definitions), has no name space (so you cannot use it as a label
or tag etc.), and since you don't create an object, you cannot take its
address. You however get a constant expression which can be used in
places where an object evaluation is not allowed.

b) Not initialize the variable and declare it as an extern (If you do
not put the extern, initialization to 0 is assumed if no other
declaration in the same compilation unit defines it). In this case,
you can make sure it gets declared in exactly one compilation unit
somehow. In that case, no other compilation unit knows what value the
object has, possibly loosing optimization opportunities, but otherwise
behaves identically.

c) Declare it as static. This gives it `internal' linkage: that is it
is the same as every other entity with the same name and internal
linkage in the compilation unit, but distinct from every object or
function of the same name in other compilation units. This takes up
space in each compilation unit, but for such small amount of stuff,
that presumably does not matter. Two things to note: (1) an extern
declaration where a declaration with internal linkage is visible (i.e.
in scope and not hidden), provides a further declaration of the entity
with internal linkage (and thus refers to the same entity), and does
not declare it with external linkage. (2) If you do declare the same
name with both internal and external linkage in the same translation
unit, you get undefined behaviour.
(C++ and C differ subtly for const objects at global scope with neither
extern nor static specified: I am obviously giving the C rules here)

d) As you did below

enum { DynamicString_stack_string_size = 256 };


This defines a new token (not a preprocessor token) which is still an
integral constant expression. Such identifiers, however, do not refer
to objects, and hence you cannot take their address, but are scoped and
obey name spaces.

Nov 15 '05 #8
Hi,

thanks for a real good explanation. I have changed it into external
linking with 'extern' and it works fine. I prefer objects in order to
avoid magic numbers during debugging.

BRs
Sune

Nov 15 '05 #9
"Sune" <su**********@hotmail.com> writes:
Hi,

Now I get the most ridiculous compile error which I'm unable to solve.
Can someone, please, help me with this? gcc output together with the
files mentioned in the gcc error output follows below. It is about 50
lines all in all, so I'm sure someone out there can find what's wrong
pretty quickly. test_main.o(.rodata+0x0): In function `t1':
/home/sune/gnu-ws/rsd2/collections/test_main.c:12: multiple definition
of `DynamicString_SUCCESS'


This means that the varible DynamicString_SUCCESS is *defined* in
multiple places. The problem is that you *define* it in a header
file that gets included in several translation units. The fix is
to *declare* the varible in the header file, and then *define* it
in only one translation unit.

*Declare* means telling the complier that there exist a name
'DynamicString_SUCCESS', which is *defined* somewhere else. If the
definition is in some other translation unit, the compiler will
let the linker resolv it.

*Define* means *declare* and in addition restore some storage for
the name.

/* Examples (assume file scope) */
extern int foo1; /* Declaration only */
int foo2; /* Declaration and definition */
int foo3 = 42; /* Declaration and definition */

extern void foo4(void); /* Declaration only */
void foo5(void); /* Declaration only */
void foo6(void) { } /* Declaration and definition */

Nov 15 '05 #10
Sune wrote without providing context:
Hi,

thanks, that was the problem.

I want to have them (DynamicString_ERROR and DynamicString_SUCCESS) in
my header accessible to clients so that clients of DynamicString can
use them to test the outcome of a call to functions I didn't include in
the code I pasted into my post.
Over and over the instructions have been posted for properly replying
when using the broken googlegroups interface. Always follow a newsgroup
before posting. This makes sure that you know what is acceptable in a
newsgroup, but also would lead to knowing how to find the FAQ and how to
use googlegroups properly.

You don't need _objects_ accessible, but only values.
What would be a more proper way of doing this? (Just beginning to get
into C you know)
Exactly as I showed you in the post to which you are replying:
If you must have these in your header, you could
#define DynamicString_ERROR 0
#define DynamicString_SUCCESS 1

Or, if you have an allergy to #defines (get over it), you might try
enum {DynamicString_ERROR, DynamicString_SUCCESS};

Or, if you positively insist on defining objects in your header, contrary to all common sense, add the 'static' qualifier.
static const int DynamicString_ERROR=0;
static const int DynamicString_SUCCESS=1;

Nov 15 '05 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

17
by: Steve Jorgensen | last post by:
If you've ever employed custom error numbers and messages in you programs, you've probably ended up with code similar to what I've ended up with in the past something like... <code> public...
5
by: Raterus | last post by:
I'm just throwing this error out for my sanity, I've seen posts about this, but never solutions. I'm using VS.NET 2003, Framework 1.1, and I'm getting a random error about every 1 out of 10 times...
3
by: Dan | last post by:
Hi, I have a problem using an aspx page with a Control on it. I get the following error message Compiler Error Message: CS1595: 'Test.Class2' is defined in multiple places; using definition...
6
by: Plat | last post by:
I've Googled this for a while, to no avail. Hopefully someone can help me. Maybe I'm using the wrong terminology. Here's the scoop! Let's say I've got a simple *.ASPX page that has a syntax...
6
by: alban | last post by:
Hello I have got some problems of compilation on a AIX IBM, I use the XLC compilator (And I can't install another one). I try to compile code Pro*c ".pc" (oracle), I need do a pre-compilation...
2
by: Ilkka | last post by:
I have created an C++ application with Windows Forms, ADO and SQL server 2005. Now I need to change something and started debugging the code. Then suddenly I receive an error. "An unhandled...
35
by: mwelsh1118 | last post by:
Why doesn't C# allow incremental compilation like Java? Specifically, in Java I can compile single .java files in isolation. The resulting individual .class files can be grouped into .jar files....
9
by: subramanian100in | last post by:
Consider the following program: #include <iostream> #include <string> #include <vector> using namespace std; template<class Tclass Vec : public vector<T> {
9
by: Raxit | last post by:
Hi, we are designing some stuff , that will generate c++ program(s) What we want is we wanted to execute that generated code.... i.e. 1. Xml based language 2. C++ code generated from 1....
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.