help with compiler directives

K

Kenneth Lantrip

trying to make something like this work...

#include <stdio.h>

int main (void) {

#if defined UNIX
printf("\n\n\n%s\n\n", "Program is running on a flavor of Unix.");
#endif

printf("Well, Is it?\n\n");
return 0;
}

Trying this under gcc in Debian. I need a way to discern whether it is
running under Win32 or Linux.

Thanks for your help.
 
S

Sam Halliday

Kenneth said:
trying to make something like this work...

#include <stdio.h>

int main (void) {

#if defined UNIX
printf("\n\n\n%s\n\n", "Program is running on a flavor of Unix.");
#endif

printf("Well, Is it?\n\n");
return 0;
}

Trying this under gcc in Debian. I need a way to discern whether it is
running under Win32 or Linux.

using defines is definitely the correct way to do this. but the easiest way to
implement it would be with code such as:

#if defined GNULINUX
printf("GNU/Linux\n");
#elif defined WINDOWS
printf("Windows\n");
#else
printf("OS not defined\n");
#endif

and then use the compiler's command line to define what OS you are on. such as
on debian GNU/Linux you might compile with

gcc -DGNULINUX test.c -o test

or on windows with

gcc -DWINDOWS test.c -o test

the actual command line args could be set by the Makefile or configuration
scripts, when ran on the target OS.

although, getting into discussions about how to define the variables on the
command line is beyond the scope of this newsgroup, as it is not about the C
language itself, but rather on implementations of it.

you could alternatively have a file "config.h" which you may include in your
file, and it could be generated automatically for the OS. that keeps command
lines much smaller :)
 
K

Kenneth Lantrip

Nils said:
#ifdef unix

Thanks, it's what I needed. I did try to scour the GNU.GCC manuals but
was unable to locate the exact part. Thanks... Now, to progress!
 
K

Kenneth Lantrip

Sam said:
using defines is definitely the correct way to do this. but the easiest way to
implement it would be with code such as:

#if defined GNULINUX
printf("GNU/Linux\n");
#elif defined WINDOWS
printf("Windows\n");
#else
printf("OS not defined\n");
#endif

and then use the compiler's command line to define what OS you are on. such as
on debian GNU/Linux you might compile with

gcc -DGNULINUX test.c -o test

or on windows with

gcc -DWINDOWS test.c -o test

Thanks for the info... It's what I needed to get going again.
 
K

Karthik

Sam said:
using defines is definitely the correct way to do this. but the easiest way to
implement it would be with code such as:

#if defined GNULINUX
printf("GNU/Linux\n");
#elif defined WINDOWS
printf("Windows\n");
#else
printf("OS not defined\n");
#endif

and then use the compiler's command line to define what OS you are on. such as
on debian GNU/Linux you might compile with

gcc -DGNULINUX test.c -o test

or on windows with

gcc -DWINDOWS test.c -o test

the actual command line args could be set by the Makefile or configuration
scripts, when ran on the target OS.

My suggestion would be to use the symbols as defined by the
implementation rather than manually specifying as mentioned above. But
in the same development environment nothing would prevent me from
setting the WINDOWS flag (probably due to a wrong makefile ) when the
compiler is invoked. As far as the headers are concerned, they would see
win32 set and they would be really happy to go ahead. In other words,
the header guards would become meaningless then.
To read the manual of the implementation would be the best thing to
do in such circumstances.
 
K

Keith Thompson

Nils O. Selåsdal said:
#ifdef unix

Both "UNIX" and "unix" are part of the user's namespace; a conforming
compiler (or a compiler being used in conforming mode) is not allowed
to predefine either symbol. <OT>For gcc, the "-ansi" option turns off
the definition of the symbol "unix".</OT>

There's likely to be a symbol in the implementation's namespace, such
as __unix or __unix__, that's defined even in conforming mode.
Consult your compiler's documentation. <OT>gcc's "-v" option shows
what the compiler does in more detail, including the preprocessor
symbols it predefines.</OT>
 
S

Sam Halliday

Karthik said:
My suggestion would be to use the symbols as defined by the
implementation rather than manually specifying as mentioned above.

but that breaks the ability to port the code to other C compilers without
intervention. as far as i am concerned... if a .c file relies on a specific c
compiler then it is not C, it is written in extended C. in this case it would be
GNU C.
 
M

Mark F. Haigh

Kenneth Lantrip said:
trying to make something like this work...

#include <stdio.h>

int main (void) {

#if defined UNIX
printf("\n\n\n%s\n\n", "Program is running on a flavor of Unix.");
#endif

printf("Well, Is it?\n\n");
return 0;
}

Trying this under gcc in Debian. I need a way to discern whether it is
running under Win32 or Linux.


Are you sure you need to do this? Really sure? If possible, choose
to code it in strict ANSI C, so you can be confident that it will work
just about anywhere, including many strange and wonderful systems that
are neither Unix nor Windows.

If you cannot do this, the best approach may be to code it using the
most common POSIX functions, which many systems provide (albiet in
varying states of usefulness).

Generally speaking, it's considered good form to isolate
system-specific preprocessor hackery (and code) instead of sprinkling
it throughout. For small projects, this may not matter, but in larger
ones, it becomes more significant. Sometimes alternate versions of
files are provided (ie blah-win32.c, blah-solaris.c, etc), which
provide a generic interface to very system-specific code.


Mark F. Haigh
(e-mail address removed)
 
A

Allin Cottrell

Do you really mean "running under", or "compiled under"? The sort of
test you indicate is a compile-time test.

This sort of test is off-topic for comp.lang.c -- you need to consult
the documentation for the compiler(s) in question. Generally, they do
define some symbols which can be used to do what you need. For example,
compilers targetted for 32-bit Windows tend to define WIN32. But don't
take my word for it, ask in the appropriate newsgroup.

Allin Cottrell
 
K

Keith Thompson

Sam Halliday said:
but that breaks the ability to port the code to other C compilers
without intervention. as far as i am concerned... if a .c file
relies on a specific c compiler then it is not C, it is written in
extended C. in this case it would be GNU C.

Symbols that are specific to an OS (like "__unix__") tend to be
supported by most or all compilers on that OS. It's not guaranteed,
of course, but compiler vendors have an interest in compatibility.
 
K

Kenneth Lantrip

Mark said:
Are you sure you need to do this? Really sure? If possible, choose
to code it in strict ANSI C, so you can be confident that it will work
just about anywhere, including many strange and wonderful systems that
are neither Unix nor Windows.

I'm pretty sure. The program is a quick hack together music catalog and
player (jukebox) program for my collection of audio media files. Seems
to be a vacume of good jukebox software for the Linux system. I'm
getting tired of waiting. So to help ween myself from Windows I'm port
one that I'd already wrote in LCC-Win32.
If you cannot do this, the best approach may be to code it using the
most common POSIX functions, which many systems provide (albiet in
varying states of usefulness).

Generally speaking, it's considered good form to isolate
system-specific preprocessor hackery (and code) instead of sprinkling
it throughout. For small projects, this may not matter, but in larger
ones, it becomes more significant. Sometimes alternate versions of
files are provided (ie blah-win32.c, blah-solaris.c, etc), which
provide a generic interface to very system-specific code.


Mark F. Haigh
(e-mail address removed)

Well, the original program used a <KenLib.c> file to add all the
funtions that weren't already included in C. There are a few Win32
calls in that file. My first thoughts on this was to conditionally
include a new <linux.c> file that would add the know-how to those Win32
calls. However, I'm now thinking it will be a bit more modding because
of all the in-efficiencies in the prepping of those calls. Using the
NCurses library is seems to be much more efficient. Some thought
adjustment is in order. As well as the muti-threading of this app.

It's a loonng way from an ANSI-C implimentation.

Thanks for your thought on the subject though.

PS... UNIX in caps isn't already defined under GCC in Debian. unix in
lowers is... JFYI

Kenneth
 
M

Mark McIntyre

A "portable" way would be to look for a specific file you know always
exists under win32. This is of course only portable to versions of windows
which have this file....
Are you sure you need to do this? Really sure? If possible, choose
to code it in strict ANSI C, so you can be confident that it will work
just about anywhere, including many strange and wonderful systems that
are neither Unix nor Windows.

Good advice.
 
K

Keith Thompson

Mark McIntyre said:
On 18 Jul 2004 18:00:36 -0700, in comp.lang.c ,


A "portable" way would be to look for a specific file you know always
exists under win32. This is of course only portable to versions of windows
which have this file....

That's a run-time check, which isn't going to be very useful if you're
trying to decide whether to include a system-specific header, or
whether to call a system-specific function. (Unless you perform the
test during configuration, but even then checking for the existence of
a file probably isn't the cleanest approach.)
 
K

Keith Thompson

Kenneth Lantrip said:
PS... UNIX in caps isn't already defined under GCC in Debian. unix
in lowers is... JFYI

Not if the compiler is invoked in conforming mode, since "unix" is
part of the user's namespace. For example, the following is a
strictly conforming program that will break if "unix" is predefined:

int main(void)
{
int unix = 0;
return 0;
}

Look for another symbol like "__unix__", which is part of the
implementation's namespace. <OT>gcc -v should show you which symbols
it predefines.</OT>
 
L

Larry Doolittle

Kenneth Lantrip said:
PS... UNIX in caps isn't already defined under GCC in Debian. unix
in lowers is... JFYI

Not if the compiler is invoked in conforming mode, since "unix" is
part of the user's namespace. For example, the following is a
strictly conforming program that will break if "unix" is predefined: [chop]
Look for another symbol like "__unix__", which is part of the
implementation's namespace. <OT>gcc -v should show you which symbols
it predefines.</OT>

ITYM

$ touch blank.c
$ gcc -E -dM -c blank.c
(true to form, this shows "#define unix 1")
$ gcc -ansi -E -dM -c blank.c
(shows only the symbols that c.l.c regulars approve of,
i.e., those that start with "__", such as __unix and __unix__)
$

- Larry
 
P

Peter Nilsson

Larry Doolittle said:
$ touch blank.c
$ gcc -E -dM -c blank.c
(true to form, this shows "#define unix 1")
$ gcc -ansi -E -dM -c blank.c
(shows only the symbols that c.l.c regulars approve of,

Not really, mine includes...

#define DJGPP 2
#define DJGPP_MINOR 3

;-)
 
M

Mark F. Haigh

Well, the original program used a <KenLib.c> file to add all the
funtions that weren't already included in C. There are a few Win32
calls in that file. My first thoughts on this was to conditionally
include a new <linux.c> file that would add the know-how to those Win32
calls. However, I'm now thinking it will be a bit more modding because
of all the in-efficiencies in the prepping of those calls. Using the
NCurses library is seems to be much more efficient. Some thought
adjustment is in order. As well as the muti-threading of this app.

If it's not a performance-sensitive application, and it appears not to
be, you should thoroughly consider whether or not coding it in C is
even a good idea. A rapid prototyping language may be a better fit
for you (unless you're a glutton for punishment, in which case you're
in good company here).

<OT>
You might think about using Perl's Curses::UI module, Python's
wxPython (http://www.wxpython.org), or C++ with wxWindows
(http://www.wxwindows.com) for approaches that will allow you to run
or compile the same source on different platforms, with a native
look-and-feel on each.
</OT>


Mark F. Haigh
(e-mail address removed)
 
M

Mark McIntyre

That's a run-time check, which isn't going to be very useful if you're
trying to decide whether to include a system-specific header, or
whether to call a system-specific function.

I thought that was what he was looking for. If its a compile-time check
then a read of his compiler manual will give him more than enough #defines
to be going on with. Or for that matter the source for any portable gnu
application, such as gnuplot or gcc.
 
A

Allin Cottrell

Mark said:
I thought that was what he was looking for. If its a compile-time check
then a read of his compiler manual will give him more than enough #defines
to be going on with. Or for that matter the source for any portable gnu
application, such as gnuplot or gcc.

<OT>
gnuplot is not a gnu application, portable or otherwise. However, it
does exemplify compile-time testing for various OSes.
</OT>

Allin Cottrell
 

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

No members online now.

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top