From: David Schwartz on
On Feb 22, 10:11 pm, Phred Phungus <Ph...(a)example.invalid> wrote:

> Another way to ask my question might be this.  When I run this command:
>
> gcc e4.c -E  -x c - >text1.txt
>
> , and search for _PC_PATH_MAX
>
> , I was expecting to see
>
> #define _PC_PATH_MAX  42
>
> , but the search turned up nothing.  Why?

Because you are looking at the *output* from the pre-processor --
that's what '-E' means. Since "#define" is a pre-processor command, it
is in the input to the pre-processor and not its output.

DS
From: Eric Sosman on
On 2/23/2010 12:45 AM, David Schwartz wrote:
> On Feb 22, 9:40 pm, Phred Phungus<Ph...(a)example.invalid> wrote:
>
>> _PC_NAME_MAX
>> The maximum number of bytes in a file name.
>>
>> _PC_PATH_MAX
>> The maximum number of bytes in a pathname.
>>
>> Why are these ultimate two values integers?
>
> You mean over something like pathconf(foo, "PC_NAME_MAX")? Efficiency.
> Passing pointers and strings between kernel and user space is much
> more expensive than passing an integer. So when an integer will do,
> that's what is done.
> [...]

Also, (and IMHO more important): typos are detected at
compile time instead of at run time. Compare and contrast:

pathconf(path, _PC_NAMEMAX); // compiler whines
pathconf(path, "PC_NAMEMAX"); // compiler happy, but ...

--
Eric Sosman
esosman(a)ieee-dot-org.invalid
From: Geoff Clare on
Nicolas George wrote:

> Phred Phungus wrote in message <7uh9suFq2tU1(a)mid.individual.net>:
>
> The other reason is that, at least on GNU systems, the symbolics constants
> for pathconf are defined as an enumerated type, somewhere in
> bits/confname.h. And on top of that, the header defines macro that expand to
> themselves, to allow #ifdef tests.
>
> Enumerated types behave exactly like the integers they represent

Except in preprocessor directives. The macros that expand to themselves
mean they can be used with #ifdef, but you can't test their values
with #if (they are treated as having value 0). Not a problem with
the pathconf constants, but it would be for some others.

The latest POSIX/UNIX standard is careful to specify which constants
must have values usable in #if. At the time those cases were decided,
glibc had some that were done as enums (and therefore not conforming).
They may have been changed since then.

--
Geoff Clare <netnews(a)gclare.org.uk>


From: Phred Phungus on
Keith Thompson wrote:
> Phred Phungus <Phred(a)example.invalid> writes:

>> #define _PC_PATH_MAX _PC_PATH_MAX
>
> The man page should be enough to tell you that _PC_PATH_MAX is some
> kind of integer expression, probably constant, and that you don't
> really need to know how it's defined; it's sufficient to know that its
> value is distinct from the values of the other _PC_* constants. Pass
> it as the second argument to pathconf, and it should do what it's
> supposed to do.
>
> If you're curious, the output of "gcc -E -dM" probably isn't the best
> thing to look at. Here's what I just did (results on your system may
> vary):
>
> $ grep -rl _PC_PATH_MAX /usr/include
> /usr/include/bits/confname.h
> $ view /usr/include/bits/confname.h
>
> A look at confname.h shows that _PC_PATH_MAX is an enumeration
> constant, and it's additionally defined as a macro that expands to
> itself. I suspect the _PC_* constants were defined as enumeration
> constants because it's convenient, and the macros are there because
> POSIX requires them and/or because it allows you to write
> #ifdef _PC_PATH_MAX
> ...
> #endif
>
> As far as I can tell, asking why these values are integers isn't
> really a very meaningful question; the only direct response I could
> give is "Why not? What would you expect them to be?".
>
> So what is it you really want to know?
>

We're getting pretty close. The enumeration is just like you say:

/* Values for the NAME argument to `pathconf' and `fpathconf'. */
enum
{
_PC_LINK_MAX,
#define _PC_LINK_MAX _PC_LINK_MAX
_PC_MAX_CANON,
#define _PC_MAX_CANON _PC_MAX_CANON
_PC_MAX_INPUT,
#define _PC_MAX_INPUT _PC_MAX_INPUT
_PC_NAME_MAX,
#define _PC_NAME_MAX _PC_NAME_MAX
_PC_PATH_MAX,
#define _PC_PATH_MAX _PC_PATH_MAX

_PC_PATH_MAX is the fifth entry, so this makes sense:

$ ./out
path_max is 4096
name_max is 255
_PC_PATH_MAX is 4
buf_size is 4353
$

Can you say a few more words about the macro expansion? Why would
#define _PC_NAME_MAX
not work in its stead?
--
fred
From: Keith Thompson on
Phred Phungus <Phred(a)example.invalid> writes:
[...]
> We're getting pretty close. The enumeration is just like you say:
>
> /* Values for the NAME argument to `pathconf' and `fpathconf'. */
> enum
> {
> _PC_LINK_MAX,
> #define _PC_LINK_MAX _PC_LINK_MAX
> _PC_MAX_CANON,
> #define _PC_MAX_CANON _PC_MAX_CANON
> _PC_MAX_INPUT,
> #define _PC_MAX_INPUT _PC_MAX_INPUT
> _PC_NAME_MAX,
> #define _PC_NAME_MAX _PC_NAME_MAX
> _PC_PATH_MAX,
> #define _PC_PATH_MAX _PC_PATH_MAX
>
> _PC_PATH_MAX is the fifth entry, so this makes sense:
>
> $ ./out
> path_max is 4096
> name_max is 255
> _PC_PATH_MAX is 4
> buf_size is 4353
> $
>
> Can you say a few more words about the macro expansion? Why would
> #define _PC_NAME_MAX
> not work in its stead?

Because "#define _PC_NAME_MAX" would cause _PC_NAME_MAX to expand to
nothing.

In your program, you have a reference to _PC_NAME_MAX.

The preprocessor sees "#define _PC_NAME_MAX _PC_NAME_MAX" and then
replaces _PC_NAME_MAX by _PC_NAME_MAX. (This effectively does
nothing, but the fact that it's #defined at all means you can use it
with #ifdef.)

Then during compilation, the identifier _PC_NAME_MAX resolves to the
enumeration constant, so it's as if you had written 4.

If instead the header had "#define _PC_NAME_MAX", it would still work
with #ifdef, but the macro name would never resolve to the enumeration
constant.

--
Keith Thompson (The_Other_Keith) kst-u(a)mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"