Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

GCC, ANSI C and function realpath

377 views
Skip to first unread message

August Karlstrom

unread,
Feb 26, 2015, 12:14:30 PM2/26/15
to
Is there a way to compile the C program below with the GCC options
`-ansi -pedantic'? If not, is there any other way to get the absolute
path of the running program and ensuring ANSI C conformance?

$ cat test.c
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
char path[PATH_MAX];
char *pathPointer;
int error;

pathPointer = realpath(argv[0], path);
if (pathPointer != NULL) {
puts(path);
error = 0;
} else {
fprintf(stderr, "realpath failed: %s\n", strerror(errno));
error = 1;
}
return error;
}

$ gcc -ansi -pedantic -D_POSIX_SOURCE -Wall -o test test.c
test.c: In function ‘main’:
test.c:13:2: warning: implicit declaration of function ‘realpath’
[-Wimplicit-function-declaration]
test.c:13:14: warning: assignment makes pointer from integer without a
cast [enabled by default]


-- August

Eric Sosman

unread,
Feb 26, 2015, 12:30:44 PM2/26/15
to
On 2/26/2015 12:14 PM, August Karlstrom wrote:
> Is there a way to compile the C program below with the GCC options
> `-ansi -pedantic'? If not, is there any other way to get the absolute
> path of the running program and ensuring ANSI C conformance?
> [...]
> $ gcc -ansi -pedantic -D_POSIX_SOURCE -Wall -o test test.c
> test.c: In function ‘main’:
> test.c:13:2: warning: implicit declaration of function ‘realpath’

According to http://linux.die.net/man/3/realpath you need
one of

-D_BSD_SOURCE
or
-D_XOPEN_SOURCE=500
or
-D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED

instead of

-D_POSIX_SOURCE

The resulting program cannot be strictly conforming.

--
eso...@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM

Nicolas George

unread,
Feb 26, 2015, 12:42:50 PM2/26/15
to
August Karlstrom , dans le message <mcnk9h$j0d$1...@speranza.aioe.org>, a
écrit :
> If not, is there any other way to get the absolute
> path of the running program and ensuring ANSI C conformance?

Why do you want it? You are probably doing something wrong.

> pathPointer = realpath(argv[0], path);

This is not the path of your program, this is just an argument put there by
the caller. The shell usually put the name of the program, but that is just
an habit. And even so, if the command was found using $PATH, it just holds
the base name.

August Karlstrom

unread,
Feb 26, 2015, 2:26:26 PM2/26/15
to
On 2015-02-26 18:30, Eric Sosman wrote:
> On 2/26/2015 12:14 PM, August Karlstrom wrote:
>> Is there a way to compile the C program below with the GCC options
>> `-ansi -pedantic'? If not, is there any other way to get the absolute
>> path of the running program and ensuring ANSI C conformance?
>> [...]
>> $ gcc -ansi -pedantic -D_POSIX_SOURCE -Wall -o test test.c
>> test.c: In function ‘main’:
>> test.c:13:2: warning: implicit declaration of function ‘realpath’
>
> According to http://linux.die.net/man/3/realpath you need
> one of
>
> -D_BSD_SOURCE
> or
> -D_XOPEN_SOURCE=500
> or
> -D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED
>
> instead of
>
> -D_POSIX_SOURCE

OK, thanks.

> The resulting program cannot be strictly conforming.

Indeed but at least GCC will tell me if I (inadvertently) use any GCC
extensions to ANSI C.


-- August

August Karlstrom

unread,
Feb 26, 2015, 2:39:36 PM2/26/15
to
On 2015-02-26 18:42, Nicolas George wrote:
> August Karlstrom , dans le message <mcnk9h$j0d$1...@speranza.aioe.org>, a
> écrit :
>> If not, is there any other way to get the absolute
>> path of the running program and ensuring ANSI C conformance?
>
> Why do you want it? You are probably doing something wrong.
[...]
> if the command was found using $PATH, it just holds
> the base name.

Ah, of course. I didn't think of that.

I'm working on a software project where the subdirectories of the
project directory (e.g. bin and lib/foo) matches the subdirectories of
the installation directory (e.g. /usr/local or ~/.local). With this
design I reason that it is possible to get the library path given the
path of a binary in the bin directory at run-time without the need for
an environment variable or compiling the path into the binary. The
question is how I can retrieve the path prefix then.


-- August

Barry Margolin

unread,
Feb 26, 2015, 2:54:40 PM2/26/15
to
In article <mcnspi$91h$1...@speranza.aioe.org>,
Try to find a copy of the comp.unix.programmer FAQ, there should be some
discussion of the issues with this in there.

--
Barry Margolin, bar...@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***

Rainer Weikusat

unread,
Feb 26, 2015, 2:55:34 PM2/26/15
to
August Karlstrom <fusio...@gmail.com> writes:
> Is there a way to compile the C program below with the GCC options
> -ansi -pedantic'? If not, is there any other way to get the absolute
> path of the running program and ensuring ANSI C conformance?

There is no way to 'ensure ANSI conformance' with gcc options, cf

Some users try to use `-pedantic' to check programs for strict ISO
C conformance. They soon find that it does not do quite what they
want: it finds some non-ISO practices, but not all--only those for
which ISO C _requires_ a diagnostic, and some others for which
diagnostics have been added.

A feature to report any failure to conform to ISO C might be
useful in some instances, but would require considerable
additional work and would be quite different from `-pedantic'. We
don't have plans to support such a feature in the near future.
[gcc 4.7 docs, section 3.8]


August Karlstrom

unread,
Feb 27, 2015, 5:20:31 AM2/27/15
to
What I'm looking for is the C equivalent of the shell command `dirname
$(readlink --canonicalize "$0")'. The function `readlink' in unistd.h
has no canonicalization options, so the question is what function(s) do
I need?


-- August

Nicolas George

unread,
Feb 27, 2015, 6:13:33 AM2/27/15
to
August Karlstrom , dans le message <mcpgd5$h6r$1...@speranza.aioe.org>, a
écrit :
> What I'm looking for is the C equivalent of the shell command `dirname
> $(readlink --canonicalize "$0")'.

You can do that in shell, because the shell is interpreted and therefore
requires to be able to find the script source. That does not work with
normal binaries.

The basic design is wrong, an Unix application should not be trying to guess
where it is installed.

Kaz Kylheku

unread,
Feb 27, 2015, 6:46:12 AM2/27/15
to
On 2015-02-26, August Karlstrom <fusio...@gmail.com> wrote:
> Is there a way to compile the C program below with the GCC options
> `-ansi -pedantic'? If not, is there any other way to get the absolute
> path of the running program and ensuring ANSI C conformance?

Note that GCC does not come with a complete C library, only very minimal
run-time support.

Roughly speaking, -ansi does two things. It disables certain non-conforming
language extensions in the compiler, and it defines the __STRICT_ANSI__
macro.

How third party library headers react to that macro is up to them.

The correct way to react to the macro is to hide all non-ANSI-C extensions,
and, secondly, also ensure that no language extensions are used in the header
itself that will break under -ansi.

SEcondly, the correct way to reveal extensions (like for instance the POSIX
fileno function in <stdio.h>) is to react to feature selection macros like
_POSIX_SOURCE (usually specified as -D_POSIX_SOURCE on the command line).

Unfortunately, environments do not implement this correctly.

* Cygwin: -ansi unconditionally hides all library extensions even if
you have feature selection macros like -D_POSIX_SOURCE.

* FreeBSD, possibly other BSDs: these people believe that feature
macros *restrict* rather than *reveal*. So for instance -D_POSIX_SOURCE means,
to the BSD people, not "please add 1990 POSIX to my order", but rather "I want
nothing but 1990 POSIX to be on my plate". So for instance -ansi and
-D_POSIX_SOURCE specifies a redundant intersection, equivalent to just -ansi,
because the fact that you specified -ansi means you want nothing but ANSI C:
no POSIX or anything else. In particular, if you want POSIX plus some
traditional BSD functions (ironically!) you can't do it in any documented way.
You do -D_POSIX_C_SOURCE=whatever and then add -D__BSD_VISIBLE, which is an
internal macro you're not supposed to be using.
In a sane environment like the GNU C Library, you just do -D_POSIX_SOURCE
and -D_BSD_SOURCE. Done! You have daemon in <unistd.h> and you have fileno
in <stdio.h>

* OS/X: Here, you just give up and use -D_DARWIN_C_SOURCE; `nuff said.

* MinGW: similar issues to Cygwin.

If you want to just switch the compiler to ANSI C mode, but not fight
the damned system header files, I recommend trying the following workaround,
with a caveat:

gcc -ansi -U__STRICT_ANSI__

The caveat is that this will screw up with header files which rely on
__STRICT_ANSI__ for conditionally selecting between ANSI constructs
and GCC extensions.

I use this as a workaround on broken platforms, not unconditionally.

Kaz Kylheku

unread,
Feb 27, 2015, 6:47:33 AM2/27/15
to
On 2015-02-26, Eric Sosman <eso...@comcast-dot-net.invalid> wrote:
> On 2/26/2015 12:14 PM, August Karlstrom wrote:
>> Is there a way to compile the C program below with the GCC options
>> `-ansi -pedantic'? If not, is there any other way to get the absolute
>> path of the running program and ensuring ANSI C conformance?
>> [...]
>> $ gcc -ansi -pedantic -D_POSIX_SOURCE -Wall -o test test.c
>> test.c: In function ‘main’:
>> test.c:13:2: warning: implicit declaration of function ‘realpath’
>
> According to http://linux.die.net/man/3/realpath you need
> one of
>
> -D_BSD_SOURCE
> or
> -D_XOPEN_SOURCE=500
> or
> -D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED
>
> instead of
>
> -D_POSIX_SOURCE
>
> The resulting program cannot be strictly conforming.

That is almost completely irrelevant. No program is strictly conforming as soon
as it does anything even remotely useful, including use of any third party
library that is not in POSIX or BSD.

Eric Sosman

unread,
Feb 27, 2015, 8:55:24 AM2/27/15
to
Your second sentence is correct, and that was my point.
"Strictly conforming" is a very high bar, so high that few
programs (and almost no "useful" programs) can clear it.

Your first sentence is incorrect, because the O.P.
specifically asked about "ensuring ANSI C conformance."

Stephen Fisher

unread,
Feb 27, 2015, 1:20:33 PM2/27/15
to
On 2015-02-26, August Karlstrom <fusio...@gmail.com> wrote:

> I'm working on a software project where the subdirectories of the
> project directory (e.g. bin and lib/foo) matches the subdirectories of
> the installation directory (e.g. /usr/local or ~/.local). With this
> design I reason that it is possible to get the library path given the
> path of a binary in the bin directory at run-time without the need for
> an environment variable or compiling the path into the binary. The
> question is how I can retrieve the path prefix then.

Have you considered using GNU libtool? It has magic to handle
situations like that: you can use libtool --mode=execute <binary> to
setup the linking even when it isn't installed for example.

Kaz Kylheku

unread,
Feb 27, 2015, 6:31:56 PM2/27/15
to
Ah, but that's conformance of the implementation, not of his program!

He wants a compiler that disables any of its nonconforming extensions and
accepts ANSI C, and possibly also one which also diagnoses everything that ANSI
C requires to be diagnosed.

August Karlstrom

unread,
Mar 1, 2015, 6:08:07 AM3/1/15
to
On 2015-02-27 12:13, Nicolas George wrote:
> August Karlstrom , dans le message <mcpgd5$h6r$1...@speranza.aioe.org>, a
> écrit :
>> What I'm looking for is the C equivalent of the shell command `dirname
>> $(readlink --canonicalize "$0")'.
>
> You can do that in shell, because the shell is interpreted and therefore
> requires to be able to find the script source. That does not work with
> normal binaries.

Thanks for the information. I solved the problem by passing the path
prefix through an environment variable instead.

> The basic design is wrong, an Unix application should not be trying to guess
> where it is installed.

I need to be able to run the application from the project directory
(before it's installed).


-- August

Nicolas George

unread,
Mar 1, 2015, 12:09:32 PM3/1/15
to
August Karlstrom , dans le message <mcurui$ld5$1...@speranza.aioe.org>, a
écrit :
> Thanks for the information. I solved the problem by passing the path
> prefix through an environment variable instead.

That is the good Unix way of doing it. But do not forget to hardcode a
fallback value for the cleanly installed version.

> I need to be able to run the application from the project directory

Everybody does.
0 new messages