Parsing a path name

K

Keith Thompson

Paul Connolly said:
The main problem is that it modifies the string it acts on. In the
particular case, you're getting it from getenv(). The standard says
about that function:

Returns

[#4] The getenv function returns a pointer to a string
associated with the matched list member. The string pointed
to shall not be modified by the program, but may be
overwritten by a subsequent call to the getenv function. If
the specified name cannot be found, a null pointer is
returned.

So to use strtok() in a defined manner, you would have to make a copy
of the string first, which might be an unnecessary step. Without more
details on what you mean by "parse" and what you will do with the
resultant parsed information, it's hard to say what will be most useful.

why doesn't getenv return a const char *?

Probably for historical reasons. My guess is that the getenv()
function predates the introduction of "const" to the C language.
Existing code that did something like this:

char *foo = getenv("FOO");

would have been broken by such a change. It's similar to the fact
that string literals aren't const; ideally they should be, but it
would have broken existing code.
 
I

Ian Collins

Paul said:
drhowarddrfine said:
So what's wrong with strtok?

The main problem is that it modifies the string it acts on. In the
particular case, you're getting it from getenv(). The standard says
about that function:

Returns

[#4] The getenv function returns a pointer to a string
associated with the matched list member. The string pointed
to shall not be modified by the program, but may be
overwritten by a subsequent call to the getenv function. If
the specified name cannot be found, a null pointer is
returned.



So to use strtok() in a defined manner, you would have to make a copy
of the string first, which might be an unnecessary step. Without more
details on what you mean by "parse" and what you will do with the
resultant parsed information, it's hard to say what will be most useful.

why doesn't getenv return a const char *?
Because it predates the widespread use of const char*. Existing code
would break if it where changed.
 
P

Paul Connolly

Keith Thompson said:
[...]
Probably for historical reasons. My guess is that the getenv()
function predates the introduction of "const" to the C language.
Existing code that did something like this:

char *foo = getenv("FOO");

would have been broken by such a change. It's similar to the fact
that string literals aren't const; ideally they should be, but it
would have broken existing code.
Haven't literal strings been treated more strictly? (and justly so) -
vaguely remember having to set a "rewritable-strings" option on old code
with gcc - the new versions of gcc says this will no longer be supported.
 
K

Keith Thompson

Paul Connolly said:
Keith Thompson said:
[...]
Probably for historical reasons. My guess is that the getenv()
function predates the introduction of "const" to the C language.
Existing code that did something like this:

char *foo = getenv("FOO");

would have been broken by such a change. It's similar to the fact
that string literals aren't const; ideally they should be, but it
would have broken existing code.
Haven't literal strings been treated more strictly? (and justly so) -
vaguely remember having to set a "rewritable-strings" option on old code
with gcc - the new versions of gcc says this will no longer be supported.

String literals aren't const in C (for historical reason), but
attempting to modify one invokes undefined behavior.

If I recall correctly, gcc has (had?) an option to treat string
literals as writable. For example:

char *s = "Hello";
s[0] = 'J';
puts(s);

would print "Jello". (The assignment invokes undefined behavior so
anything the compiler chooses to do with it is ok as far as the
standard is concerned.)

gcc also has an option to treat string literals as const, even though
the standard says they aren't. This does affect some strictly
conforming code, but only by producing some additional warnings, some
of which are confusingly worded, so it's not a conformance violation
for gcc. I have some thoughts about how this could have been done
better, but this is straying off-topic as it is.
 
P

Paul Connolly

Ian Collins said:
Because it predates the widespread use of const char*. Existing code
would break if it where changed.
It would be better if the standard defined getenv to return const char * (to
tell idiots like me that we cannot mutilate the return value) and have a
compiler switch -old-char-ptr-getenv for old code.
 
I

Ian Collins

Paul said:
It would be better if the standard defined getenv to return const char * (to
tell idiots like me that we cannot mutilate the return value) and have a
compiler switch -old-char-ptr-getenv for old code.
The standard doesn't define compiler options.

I'm afraid we are stuck with a great deal of historical baggage in the C
world. You just have to learn to live with it and read your man pages!
 
D

Default User

It would be better if the standard defined getenv to return const
char * (to tell idiots like me that we cannot mutilate the return
value)

There's tons of legacy code, including many large and sometimes
arcanely written operating systems that people would like to be able to
compile with newer compilers and not have to hack up trying to fix such
things.
and have a compiler switch -old-char-ptr-getenv for old code.

The standard doesn't define such "compiler switches". Therefore there
would be no particular reason for compiler writers to include such
functionality.




Brian
 
P

Paul Connolly

Default User said:
There's tons of legacy code, including many large and sometimes
arcanely written operating systems that people would like to be able to
compile with newer compilers and not have to hack up trying to fix such
things.


The standard doesn't define such "compiler switches". Therefore there
would be no particular reason for compiler writers to include such
functionality.

I do not lie to the compiler - but without a const the compiler lies to me.
I didn't vote for the government but that does not negate my right to
criticize - sometimes "the most patriotic thing you can do is dissent."
I am suggesting that the C standard should have made the best decision for
code going forward (and indicate problems in existing code), but compiler
writers should have a mind to pragmatically support old (and dangerous)
definitions - don't organisations that write operating systems tend to
writer compilers too? - for other users the old behaviour is easy to
replicate in a mygetenv function - which keeps a list of copies of the
getenv values that it has been asked for - and looks them up and else
getenvs then into the list and returns the copy allowing it to be mangle as
before.
Also "hack up" is the wrong description of the process required to rewrite
code to compile with a newer compiler - "improve" is a better description.
 
P

Paul Connolly

Keith Thompson said:
Paul Connolly said:
Keith Thompson said:
[...]
Probably for historical reasons. My guess is that the getenv()
function predates the introduction of "const" to the C language.
Existing code that did something like this:

char *foo = getenv("FOO");

would have been broken by such a change. It's similar to the fact
that string literals aren't const; ideally they should be, but it
would have broken existing code.
Haven't literal strings been treated more strictly? (and justly so) -
vaguely remember having to set a "rewritable-strings" option on old code
with gcc - the new versions of gcc says this will no longer be supported.

String literals aren't const in C (for historical reason), but
attempting to modify one invokes undefined behavior.

If I recall correctly, gcc has (had?) an option to treat string
literals as writable. For example:

char *s = "Hello";
s[0] = 'J';
puts(s);

would print "Jello". (The assignment invokes undefined behavior so
anything the compiler chooses to do with it is ok as far as the
standard is concerned.)
In code compiled without the "rewritable-strings" option and an ANSI
compiler which produces an executable that follows the standard's permission
to put string literals in read-only memory, this would cause an access
violation during run time. It is my understanding that in old pre-ANSI code
compiled under a pre-ANSI compiler that string literals were rewritable as
in your example, and the behaviour pre-ANSI was not undefined - is that
correct?
 
C

CBFalconer

Paul said:
.... snip ...

I do not lie to the compiler - but without a const the compiler
lies to me. I didn't vote for the government but that does not
negate my right to criticize - sometimes "the most patriotic
thing you can do is dissent." I am suggesting that the C standard
should have made the best decision for code going forward (and
indicate problems in existing code), but compiler writers should
have a mind to pragmatically support old (and dangerous)
definitions - don't organisations that write operating systems
tend to writer compilers too? - for other users the old behaviour
is easy to replicate in a mygetenv function - which keeps a list
of copies of the getenv values that it has been asked for - and
looks them up and else getenvs then into the list and returns the
copy allowing it to be mangle as before.

No pragmas (which are a sinkhole) needed. You can have just what
you want with gcc and the -Wwritestrings option. This doesn't
apply to getenv, however. No compiler will survive when it
arbitrarily makes legacy source erroneous.

--
Some informative links:
< <http://www.geocities.com/nnqweb/>
<http://www.catb.org/~esr/faqs/smart-questions.html>
<http://www.caliburn.nl/topposting.html>
<http://www.netmeister.org/news/learn2quote.html>
<http://cfaj.freeshell.org/google/>
 

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,780
Messages
2,569,611
Members
45,279
Latest member
LaRoseDermaBottle

Latest Threads

Top