473,410 Members | 1,873 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,410 software developers and data experts.

Problems about conditional compilation

Hi,

Could I ask some questions about the conditional compilaion? Suppose I
have three simple files: a.c, b.c and c.h

/* --------a.c--------- */
#include <stdio.h>
#include "c.h"

int main()
{
int temp = XXXX;
printf("%d\n", temp);
f();
return 0;
}
/* --------b.c--------- */
#include <stdio.h>
#include "c.h"

int f()
{
int temp = XXXX;
printf("%d\n", temp);
return 0;
}
/* -------c.h--------- */
#ifndef C_H_
#define C_H_
#define XXXX 100
#else
#define XXXX 900
#endif

Then, when I compile them together by gcc a.c b.c, the result shows:
100
100

I wonder why the conditional compilation does not work. I mean, when
c.h is included by a.c and b.c respectively, XXXX should by defined as
two different values. What's wrong with this understanding?

In fact, this problem comes from another one. When I try to define a
function in the header file c.h (I know, this is not a good style),
compiler complains there are duplicated definition for that function.
But the function definition section is wrapped by compilation
directives, so it should not be included twice at all.

I feel very confused about conditional compilation. Please help me or
give some clues to make it clear. Thank you all in advance.

Nov 15 '05 #1
12 2452
wanghz wrote on 11/09/05 :
Hi,

Could I ask some questions about the conditional compilaion? Suppose I
have three simple files: a.c, b.c and c.h

/* --------a.c--------- */
#include <stdio.h>
#include "c.h"

int main()
{
int temp = XXXX;
printf("%d\n", temp);
f();
return 0;
}

/* --------b.c--------- */
#include <stdio.h>
#include "c.h"

int f()
{
int temp = XXXX;
printf("%d\n", temp);
return 0;
}

/* -------c.h--------- */
#ifndef C_H_
#define C_H_
#define XXXX 100
#else
#define XXXX 900
#endif

Then, when I compile them together by gcc a.c b.c, the result shows:
100
100
Fine.
I wonder why the conditional compilation does not work.
It does.
I mean, when
c.h is included by a.c and b.c respectively,
'respectively''is the important word.
XXXX should by defined as
two different values. What's wrong with this understanding?
It's all wrong. The guard trick is against multiple inclusions, not
against multple definitions.
In fact, this problem comes from another one. When I try to define a
function in the header file c.h
Don't do that.
(I know, this is not a good style),
for a good reason your are to discover.
compiler complains there are duplicated definition for that function.
Sure.
But the function definition section is wrapped by compilation
directives, so it should not be included twice at all.
Why ?

The guard protects against this :

/* b.h */
<...>
#include "a.h"
<...>
/* xxx.c */
#include "a.h"
#include "b.h" /* second inclusion */
I feel very confused about conditional compilation. Please help me or
give some clues to make it clear. Thank you all in advance.


It's quite simple. There are usage rules that are to be followed:

- a header contains not more that the following :

* #include directives
* public macros definitions
* public constants definitions
* public types definitions
* public structures definitions
* public unions definitions
* public inline functions definitions [C99]
* public functions declarations (prototyped form highly recommended)
* public object declarations (extern)

- A header is guarded (again multiple inclusions)

#ifndef H_XXX
#define H_XXX

/* include the above here. */

#endif /* guard */

You can burn the rules, but don't come here an cry.
--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

I once asked an expert COBOL programmer, how to
declare local variables in COBOL, the reply was:
"what is a local variable?"
Nov 15 '05 #2
(supersedes <mn***********************@YOURBRAnoos.fr>)

wanghz wrote on 11/09/05 :
Hi,

Could I ask some questions about the conditional compilaion? Suppose I
have three simple files: a.c, b.c and c.h

/* --------a.c--------- */
#include <stdio.h>
#include "c.h"

int main()
{
int temp = XXXX;
printf("%d\n", temp);
f();
return 0;
}

/* --------b.c--------- */
#include <stdio.h>
#include "c.h"

int f()
{
int temp = XXXX;
printf("%d\n", temp);
return 0;
}

/* -------c.h--------- */
#ifndef C_H_
#define C_H_
#define XXXX 100
#else
#define XXXX 900
#endif

Then, when I compile them together by gcc a.c b.c, the result shows:
100
100
Fine.
I wonder why the conditional compilation does not work.
It does.
I mean, when
c.h is included by a.c and b.c respectively,
'respectively''is the important word.
XXXX should by defined as
two different values. What's wrong with this understanding?
It's all wrong. The guard trick is against multiple *inclusions*, not
against multiple *definitions*.
In fact, this problem comes from another one. When I try to define a
function in the header file c.h
Don't do that.
(I know, this is not a good style),
for good reasons your are to discover.
compiler complains there are duplicated definition for that function.
Sure.
But the function definition section is wrapped by compilation
directives, so it should not be included twice at all.
Why ?

The guard protects against this :

/* b.h */
<...>
#include "a.h"
<...>

/* xxx.c */
#include "a.h"
#include "b.h" /* second inclusion */
I feel very confused about conditional compilation. Please help me or
give some clues to make it clear. Thank you all in advance.


It's quite simple. There are usage rules that are to be followed:

- A header contains not more that the following (in that order):

* #include directives
* public macros definitions
* public constants definitions
* public types definitions
* public structures definitions
* public unions definitions
* public inline functions definitions [C99]
* public functions declarations (prototyped form highly recommended)
* public object declarations (extern)

- A header is guarded (against multiple inclusions)

#ifndef H_XXX
#define H_XXX

/* include the above here. */

#endif /* guard */

You can burn out the rules, but don't come here an cry.

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

I once asked an expert COBOL programmer, how to
declare local variables in COBOL, the reply was:
"what is a local variable?"
Nov 15 '05 #3
wanghz wrote:
Hi,

Could I ask some questions about the conditional compilaion? Suppose I
have three simple files: a.c, b.c and c.h

/* --------a.c--------- */
#include <stdio.h>
#include "c.h"

int main()
{
int temp = XXXX;
printf("%d\n", temp);
f();
return 0;
}
/* --------b.c--------- */
#include <stdio.h>
#include "c.h"

int f()
{
int temp = XXXX;
printf("%d\n", temp);
return 0;
}
/* -------c.h--------- */
#ifndef C_H_
#define C_H_
#define XXXX 100
#else
#define XXXX 900
#endif

Then, when I compile them together by gcc a.c b.c, the result shows:
100
100

I wonder why the conditional compilation does not work. I mean, when
c.h is included by a.c and b.c respectively, XXXX should by defined as
two different values. What's wrong with this understanding?

In fact, this problem comes from another one. When I try to define a
function in the header file c.h (I know, this is not a good style),
compiler complains there are duplicated definition for that function.
But the function definition section is wrapped by compilation
directives, so it should not be included twice at all.

I feel very confused about conditional compilation. Please help me or
give some clues to make it clear. Thank you all in advance.


gcc compiles every .c file as a single "program" (dont know a proper
name, correct me please if you know one), so an include in a.c does not
interfere with an include in b.c and vice versa. The "programs" will
then be linked together to the complete executable.

So C_H_ is never defined before you include c.h and hence it always
defines XXXX to be 100. The same applies to your function problem.

HTH
Nov 15 '05 #4
wanghz wrote:
Hi,

Could I ask some questions about the conditional compilaion? Suppose I
have three simple files: a.c, b.c and c.h

/* --------a.c--------- */
#include <stdio.h>
#include "c.h"

int main()
{
int temp = XXXX;
printf("%d\n", temp);
f();
return 0;
}
/* --------b.c--------- */
#include <stdio.h>
#include "c.h"

int f()
{
int temp = XXXX;
printf("%d\n", temp);
return 0;
}
/* -------c.h--------- */
#ifndef C_H_
#define C_H_
#define XXXX 100
#else
#define XXXX 900
#endif

Then, when I compile them together by gcc a.c b.c, the result shows:
100
100

I wonder why the conditional compilation does not work. I mean, when
c.h is included by a.c and b.c respectively, XXXX should by defined as
two different values. What's wrong with this understanding?
a.c and b.c are two separate translation units. They do not "see"
each other at compile time.
Most of the things the preprocessor does can be seen as some sort
of text replacement.

So, in a.c _and_ b.c, c.h is included for the first time, respectively,
thus C_H_ is not defined and you arrive at the first #define directive.

Only if you have
#include "c.h"
....
#include "c.h"
where one or both include directives can come in directly or indirectly
(i.e. via another included header), you run into the second #define.
However, this effectively means
#define XXXX 100
#define XXXX 900
which probably is not what you want at all.

Usually, the inclusion guards are there to avoid _double_ definitions
and ill effects stemming from them.

In fact, this problem comes from another one. When I try to define a
function in the header file c.h (I know, this is not a good style),
compiler complains there are duplicated definition for that function.
But the function definition section is wrapped by compilation
directives, so it should not be included twice at all.

I feel very confused about conditional compilation. Please help me or
give some clues to make it clear. Thank you all in advance.


The canonical and correct way of handling this:

/* --------a.c--------- */
#include <stdio.h>
#include "b.h"
#include "c.h"

int main (void)
{
printf("%d\n", xxxx);
g();
f();
return 0;
}

/* --------b.h--------- */
#ifndef B_H_
#define B_H_

void f (void);

#endif
/* --------b.c--------- */
#include <stdio.h>
#include "b.h"
#include "c.h"

void f (void)
{
printf("%d\n", xxxx);
g();
}

/* -------c.h--------- */
#ifndef C_H_
#define C_H_

extern int xxxx;

void g (void);

#endif

/* -------c.c--------- */
#include "c.h"

int xxxx = 42;

void g (void)
{
xxxx++;
}
Note that declaring xxxx in this way is a bad idea at best.
Giving xxxx internal linkage and creating a function returning
the value of xxxx would be safer.
Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Nov 15 '05 #5
"wanghz" <wa****@gmail.com> wrote:
Hi,

Could I ask some questions about the conditional compilaion? Suppose I
have three simple files: a.c, b.c and c.h

/* --------a.c--------- */
#include <stdio.h>
#include "c.h"

int main()
{
int temp = XXXX;
printf("%d\n", temp);
f();
return 0;
}
/* --------b.c--------- */
#include <stdio.h>
#include "c.h"

int f()
{
int temp = XXXX;
printf("%d\n", temp);
return 0;
}
/* -------c.h--------- */
#ifndef C_H_
#define C_H_
#define XXXX 100
#else
#define XXXX 900
#endif

Then, when I compile them together by gcc a.c b.c, the result shows:
100
100
Of course, since c.h is included once by a.c and, *independently*,
by b.c. Your multiple inclusion guards will work only, if c.h is
included more than once by one of your .c files. The macro
definitions in a.c are invisible in b.c.
I wonder why the conditional compilation does not work. I mean, when
c.h is included by a.c and b.c respectively, XXXX should by defined as
two different values. What's wrong with this understanding?
See above.
In fact, this problem comes from another one. When I try to define a
function in the header file c.h (I know, this is not a good style),
Indeed.
compiler complains there are duplicated definition for that function.
Actually, it's the linker which complains, since you generated
duplicate code for the functions, for the reasons given above.
But the function definition section is wrapped by compilation
directives, so it should not be included twice at all.
But it's included once by each of your source files, so you end up
having duplicate code in linking stage.
I feel very confused about conditional compilation. Please help me or
give some clues to make it clear. Thank you all in advance.


Try this, for example:

/* --------a.c--------- */
#include <stdio.h>

#include "c.h"

int main( void )
{
int temp = XXXX;
printf("%d\n", temp);
f();
return 0;
}
/* --------b.c--------- */
#include <stdio.h>

#define USE_ALTERNATE_XXXX

#include "c.h"

int f()
{
int temp = XXXX;
printf("%d\n", temp);
return 0;
}
/* -------c.h--------- */
#ifndef USE_ALTERNATE_XXXX
#define XXXX 100
#else
#define XXXX 900
#endif
Best regards
--
Irrwahn Grausewitz (ir*******@freenet.de)
welcome to clc : http://www.ungerhu.com/jxh/clc.welcome.txt
clc faq-list : http://www.faqs.org/faqs/C-faq/faq/
clc frequent answers: http://benpfaff.org/writings/clc
Nov 15 '05 #6
Hi,

Thank you for your reply :-)

I think I might have understood what is the fallacy by learning your
suggestion. Do you mean that the muliple inclusions guard is used in a
compliation unit only? That is, when precompiler is processing a
source file, for example, a.c, the guard prevent including the same
header more than one times in this file only? When it turns to a new
source file, the precomilation will restart and all remembered
defined's would be discarded. So the guard does not try to prevent
including the same header file at different source files?

I don't know whether my understanding is correct this time.

Nov 15 '05 #7
wanghz wrote on 11/09/05 :
I think I might have understood what is the fallacy by learning your
suggestion. Do you mean that the muliple inclusions guard is used in a
compliation unit only?
Yes.
That is, when precompiler is processing a
I don't know what a 'precompiler' is. Maybe you meant the
'preprocessor'.
source file, for example, a.c, the guard prevent including the same
header more than one times in this file only?
Yes.
When it turns to a new
source file, the precomilation will restart and all remembered
defined's would be discarded. So the guard does not try to prevent
including the same header file at different source files?

I don't know whether my understanding is correct this time.


Sounds all good to me.

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"There are 10 types of people in the world today;
those that understand binary, and those that dont."
Nov 15 '05 #8
Marc Thrun wrote on 11/09/05 :
gcc compiles every .c file as a single "program" (dont know a proper name,
correct me please if you know one),


'compile unit' is the official term to be used.

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

I once asked an expert COBOL programmer, how to
declare local variables in COBOL, the reply was:
"what is a local variable?"
Nov 15 '05 #9
Thank you all in advance.

All of your replies have give me a good tutorial on this topic, and
make me clear on many other related problems too.

Thank you all again!

Nov 15 '05 #10
wanghz wrote:

Hi,

Could I ask some questions about the conditional compilaion? Suppose I
have three simple files: a.c, b.c and c.h [... a.c and b.c print the value of XXXX ...] /* -------c.h--------- */
#ifndef C_H_
#define C_H_
#define XXXX 100
#else
#define XXXX 900
#endif

Then, when I compile them together by gcc a.c b.c, the result shows:
100
100

I wonder why the conditional compilation does not work. I mean, when
c.h is included by a.c and b.c respectively, XXXX should by defined as
two different values. What's wrong with this understanding?


You misunderstanding is believing that a.c and b.c are being compiled
as a single unit when they are not. Each source file listed on the
command line is compiled separately. Anything done while compiling
the first file (a.c) is thrown out when the second file (b.c) is
compiled.

Therefore, a.c's define of C_H_ no longer exists when the compiler
starts to compile b.c

Also, consider this... If you expected C_H_ to retain its definition,
why did you not expect XXXX to retain its, and therefore give a
redefinition error?

[...]

--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>

Nov 15 '05 #11
"Emmanuel Delahaye" <em***@YOURBRAnoos.fr> writes:
Marc Thrun wrote on 11/09/05 :
gcc compiles every .c file as a single "program" (dont know a proper
name, correct me please if you know one),


'compile unit' is the official term to be used.


The standard uses the term "translation unit".

--
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 #12
Das

wanghz wrote:
Hi,

Thank you for your reply :-)

I think I might have understood what is the fallacy by learning your
suggestion. Do you mean that the muliple inclusions guard is used in a
compliation unit only? That is, when precompiler is processing a
source file, for example, a.c, the guard prevent including the same
header more than one times in this file only?
Yes. That is the use of guards.
When it turns to a new
source file, the precomilation will restart and all remembered
defined's would be discarded. So the guard does not try to prevent
including the same header file at different source files?
A new file is a new job to be processed, So the state is changed to
originals.

I don't know whether my understanding is correct this time.


Thanks
Ashok.

Nov 15 '05 #13

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

Similar topics

11
by: Steven T. Hatton | last post by:
I've made no secret of the fact that I really dislike the C preprocessor in C++. No aspect of the language has caused me more trouble. No aspect of the language has cause more code I've read to be...
1
by: chris han | last post by:
Hi, all, I'm trying to use Conditional Compilation Statements in my code. using System; #define DEBUG public class MyClass { public static void Main() {
2
by: FireStarter | last post by:
Guys, in the code that follows, why does the method F() still compile, even if DBG is undefined? Inside method G(), the code inside <#if DBG> does not compile (notice that I can write whatever I...
1
by: A.M-SG | last post by:
Hi, We have a solution with several c# projects within it. How can I define solution wide conditional compilation symbols?
1
by: lavu | last post by:
Is there any way to specify a different executable name for my project based on value that I have set in my conditional compilation constant. For eg: If I have FIRST specified in my conditional...
4
by: Bob | last post by:
Hi, In VS2003 conditional compilation constants and their state could be defined at project level. I was using this to control what features where offered by various builds. i.e....
10
by: Dave | last post by:
I'm a C++ programmer of many years, trying to get my feet wet in C#. I have a question about conditional compilation. In C++, I would sometimes define a constant in an include file, and then...
1
by: Marek | last post by:
I use VS2005 with framework 2.0 and I just found a behavior I consider odd. Here is the code that illustrates th eproblem: public static void MethodA() { MethodB() } #if DEBUG
6
by: maxwell | last post by:
I'm trying to use the gpp utility (Gnu points to http://en.nothingisreal.com/wiki/GPP) to do conditional compilation in Python, and I'm running into a problem: the same '#' character introduces...
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...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 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 a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...

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.