Definition in Header files

M

Madhur

I have problems faced in adding definitions in the command header
file. I have defined a header file which includes huge set of global
constants and I am using them in all the C files.

For example my sample.h file looks like this

/*************

File : sample.h

****************/


const int a1 = 0;
const int a2 = 0;


/****End of sample.h*********/


My source code looks like this

/*****************
File:sample1.c

***********/
#include "sample.h"

int main()
{
}

/*****End of sample1.c************/

/***************
File : sample2.c
**************/

#include "sample.h

int main()
{
}

/*******End of sample2.c**********/

Now the problem is during linking it says multiple definition of
symbols a1 and a2. I can avoid this problem by having a C file which
contains the definitions and H file for declarations. But is there any
way I can avoid doing this. Please let me know.
 
U

user923005

I have problems faced in adding definitions in the command header
file. I have defined a header file which includes huge set of global
constants and I am using them in all the C files.

For example my sample.h file looks like this

/*************

File : sample.h

****************/

const int a1 = 0;
const int a2 = 0;

/****End of sample.h*********/

My source code looks like this

/*****************
File:sample1.c

***********/
#include "sample.h"

int main()
{

}

/*****End of sample1.c************/

/***************
File : sample2.c
**************/

#include "sample.h

int main()
{

}

/*******End of sample2.c**********/

Now the problem is during linking it says multiple definition of
symbols a1 and a2. I can avoid this problem by having a C file which
contains the definitions and H file for declarations. But is there any
way I can avoid doing this. Please let me know.

Global things that don't have to be global is a bad idea.
Nevertheless, you can use them {warning -- untested} as follows:

-- const.c --
#include "const.h"
int gVal = 100;
double gPi = 3.1415926535897932384626433832795;
-- end const.c --

-- const.h --
extern int gVal;
extern double gPi;
-- end const.h --

-- main.c --
#include <stdio.h>
#include "const.h"
int main(void)
{
printf("gVal = %d and gPi = %f\n", gVal, gPi);
return 0;
}
-- end main.c --
 
I

Ian Collins

Madhur said:
Now the problem is during linking it says multiple definition of
symbols a1 and a2. I can avoid this problem by having a C file which
contains the definitions and H file for declarations. But is there any
way I can avoid doing this. Please let me know.
Why avoid doing the obvious?
 
M

Madhur

Global things that don't have to be global is a bad idea.
Nevertheless, you can use them {warning -- untested} as follows:

-- const.c --
#include "const.h"
int gVal = 100;
double gPi = 3.1415926535897932384626433832795;
-- end const.c --

-- const.h --
extern int gVal;
extern double gPi;
-- end const.h --

-- main.c --
#include <stdio.h>
#include "const.h"
int main(void)
{
printf("gVal = %d and gPi = %f\n", gVal, gPi);
return 0;}

-- end main.c --

Here are a1 and a2 are global variables and I will be using in both
sample1.c and sample2.c files.
This what I wanted to avoid.. as indicated by me
 
M

Madhur

Why avoid doing the obvious?

I want those variable to be const. Defining them in a C file , I can
not declare them as const.
Why doesn't C compilation doesn't support Internal linkage as it is
supported by C++??
 
R

robertwessel2

I have problems faced in adding definitions in the command header
file. I have defined a header file which includes huge set of global
constants and I am using them in all the C files.

For example my sample.h file looks like this

/*************

File : sample.h

****************/

const int a1 = 0;
const int a2 = 0;

/****End of sample.h*********/

My source code looks like this

/*****************
File:sample1.c

***********/
#include "sample.h"

int main()
{

}

/*****End of sample1.c************/

/***************
File : sample2.c
**************/

#include "sample.h

int main()
{

}

/*******End of sample2.c**********/

Now the problem is during linking it says multiple definition of
symbols a1 and a2. I can avoid this problem by having a C file which
contains the definitions and H file for declarations. But is there any
way I can avoid doing this. Please let me know.


Well, no really good ways.

You can do like you suggested and put the definitions in a separate
file. This is probably the best approach, but has the obvious problem
of considerable duplication.

A second possibility is to make all of these constants static as
well. That solves the multiple definition problem, but duplicates the
constants in each module that includes the header. Depending on the
exact definition of "huge" and the number of times the header is
included, this may result in an unacceptable expansion of the
executable.

Third you could keep the definitions in the header, but play
preprocessor games so that when most users of the constants include
the header, the initializations are omitted. For example:

const int a1
#ifdef IN_DEFINING_MODULE
= 0
#endif
;

The you'd have a const.c which included const.h along with the
#define:

/* const.c */
#define IN_DEFINING_MODULE
#include "const.h"

This is obviously ugly, but it does work.

As others have pointed out, it's probably a sign of a design problem
if you have "huge" numbers of global constants, so you may want to
start by rethinking your design.
 
U

user923005

I want those variable to be const. Defining them in a C file , I can
not declare them as const.

Of course you can.
Why doesn't C compilation doesn't support Internal linkage as it is
supported by C++??

We might ask, why doesn't C support block data statements like
Fortran?

At any rate, you can have external const in C. The code you posted
should not work in C++ either. Every time you include that header
file, it defines a new instance of the variables.

C:\tmp>cl /W4 /Ox const.c main.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.762
for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.

const.c
main.c
Generating Code...
Microsoft (R) Incremental Linker Version 8.00.50727.762
Copyright (C) Microsoft Corporation. All rights reserved.

/out:const.exe
const.obj
main.obj

C:\tmp>lin const.c main.c

C:\tmp>"C:\Lint\Lint-nt" +v -i"C:\Lint" std.lnt -os(_LINT.TMP)
const.c main.c
PC-lint for C/C++ (NT) Vers. 8.00u, Copyright Gimpel Software
1985-2006

--- Module: const.c (C)

--- Module: main.c (C)

C:\tmp>type _LINT.TMP | more

--- Module: const.c (C)

--- Module: main.c (C)

---
output placed in _LINT.TMP

C:\tmp>type const.c
#include "const.h"
const int gVal = 100;
const double gPi = 3.1415926535897932384626433832795;

C:\tmp>type const.h
#ifndef CONST_H_INCLUDED
#define CONST_H_INCLUDED

extern const int gVal;
extern const double gPi;

#endif /* CONST_H_INCLUDED */


C:\tmp>type main.c

#include <stdio.h>
#include "const.h"
int main(void)
{
printf("gVal = %d and gPi = %f\n", gVal, gPi);
return 0;
}


C:\tmp>const
gVal = 100 and gPi = 3.141593
 
I

Ian Collins

*Please* don't quote signatures.
I want those variable to be const. Defining them in a C file , I can
not declare them as const.

Nonsense, how else would one declare an extern constant?
Why doesn't C compilation doesn't support Internal linkage as it is
supported by C++??
C isn't C++.
 
I

Ian Collins

Well, no really good ways.

You can do like you suggested and put the definitions in a separate
file. This is probably the best approach, but has the obvious problem
of considerable duplication.
Where?
 
R

robertwessel2



The definitions in the proposed const.c largely duplicates the
declarations in const.h, and introduces the usual double maintenance
problems. How severe those are is dependent on the situation.
 
U

user923005

The definitions in the proposed const.c largely duplicates the
declarations in const.h, and introduces the usual double maintenance
problems. How severe those are is dependent on the situation.

OK. You want to access public objects from 100 files.
How would you do it?
 
R

robertwessel2

OK. You want to access public objects from 100 files.
How would you do it?


As I said, there's not really a great way in C, all the approaches
have issues, the best one for the OP will depend on his exact
situation. Some other languages have better ways to define interfaces
than C, or have a better notion of what a "constant" is, where
"better" defined is in terms of solving the OP's problem, but those
are rather OT.
 
U

user923005

As I said, there's not really a great way in C, all the approaches
have issues, the best one for the OP will depend on his exact
situation. Some other languages have better ways to define interfaces
than C, or have a better notion of what a "constant" is, where
"better" defined is in terms of solving the OP's problem, but those
are rather OT.

I am not wondering how you would do it in another language. I am
wondering about your less redundant method to do it in C.
 
R

robertwessel2

I am not wondering how you would do it in another language. I am
wondering about your less redundant method to do it in C.


What part of "there's not really a great way in C" is not clear? Or
my earlier post where I outlined three approaches, and their
limitations, to the problem at hand?
 
R

Road Tang

Madhur wrote:

Now the problem is during linking it says multiple definition of
symbols a1 and a2. I can avoid this problem by having a C file which
contains the definitions and H file for declarations. But is there any
way I can avoid doing this. Please let me know.

Yes, In C++ , it's not a problem. but In C, it's a compile error.
I suggest you to use macro to define const-like value.

#define A1 0
#define A2 0

If you think there are const variable, and won't change them, then
the macro is better choice for you in C.

C is C, and C++ is C++. Each one has its own solution and convention.

-Road
 
I

Ian Collins

Road said:
Madhur wrote:



Yes, In C++ , it's not a problem. but In C, it's a compile error.
I suggest you to use macro to define const-like value.

#define A1 0
#define A2 0
Yuck.

If you think there are const variable, and won't change them, then
the macro is better choice for you in C.

C is C, and C++ is C++. Each one has its own solution and convention.
and macros aren't the best option in either. If a value doe not have to
be a compile time constant in C, use extern const <type>. If it does,
use an enum.
 
R

Road Tang

....snip ....
We might ask, why doesn't C support block data statements like
Fortran?

At any rate, you can have external const in C. The code you posted
should not work in C++ either. Every time you include that header
file, it defines a new instance of the variables.

It's really a problem to use multiple const variable like this.

but yes, the code works well in C++, though not in C.

-Road
 
R

Road Tang

Ian said:
and macros aren't the best option in either. If a value doe not have to
be a compile time constant in C, use extern const <type>. If it does,
use an enum.

Well, i said the macro is just "better".
and enum and extern const maybe a more better solution,
if your two "if"s are true.

but what would you do if you just want a const double value,
and use it everwhere, but doesn't bother where definition it is?

So macro have its position.

I doesn't claim something is the best absolutely.
You know, it depends what you require.

-Road.
 
P

pete

Madhur said:
I have problems faced in adding definitions in the command header
file. I have defined a header file which includes huge set of global
constants and I am using them in all the C files.

For example my sample.h file looks like this

/*************

File : sample.h

****************/

const int a1 = 0;
const int a2 = 0;

/****End of sample.h*********/

My source code looks like this

/*****************
File:sample1.c

***********/
#include "sample.h"

int main()
{
}

/*****End of sample1.c************/

/***************
File : sample2.c
**************/

#include "sample.h

int main()
{
}

/*******End of sample2.c**********/

Now the problem is during linking it says multiple definition of
symbols a1 and a2.

How many different programs is that supposed to be?
There's only one function named "main" in a program.
It looks like you're trying to link two different programs together.
I can avoid this problem by having a C file which
contains the definitions and H file for declarations.

You're talking about avoiding the right way to write C code.
 
C

Charlie Gordon

Ian Collins said:
and macros aren't the best option in either. If a value doe not have to
be a compile time constant in C, use extern const <type>. If it does,
use an enum.

you can only use enum for a constant of type int, and even that can be an
issue because sizeof(enum toto) is not necessarily the same as sizeof(int).
for a double you have to use a macro or a global const variable.
You can make that static, but it may lead to space wastage and the compiler
might complain about static variables being defined but not used.
It would be useful to have a way to tell the compiler that a global variable
is meant to be used as a constant value. I propose to extend the meaning of
inline for this purpose:

static inline double const PI = 3.14159265358979323846;
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,818
Latest member
Brigette36

Latest Threads

Top