getdelim: wrong specs

J

jacob navia

Richard Bos a écrit :
True. But so is...




...this.

You have been given errno by the Standard. Use it.

Richard

The problems of errno are many... You have to avoid forgetting to
set it to zero before calling the function, and it is an ugly global
variable. Why is a result value a bad design? Can you explain?
 
M

matevzb

jacob said:
The problems of errno are many... You have to avoid forgetting to
set it to zero before calling the function, and it is an ugly global
variable. Why is a result value a bad design? Can you explain?

HPUX 11.0:
extern int *__errno(void);
#define errno (*__errno())

Solaris 7:
#if (defined(_REENTRANT) || defined(_TS_ERRNO) || \
_POSIX_C_SOURCE - 0 >= 199506L) && !(defined(lint) ||
defined(__lint))
extern int *___errno();
#define errno (*(___errno()))
....

And similar on Linux & others I believe. Of course, it _can_ as well be
a global variable...
 
J

jacob navia

matevzb a écrit :
HPUX 11.0:
extern int *__errno(void);
#define errno (*__errno())

Solaris 7:
#if (defined(_REENTRANT) || defined(_TS_ERRNO) || \
_POSIX_C_SOURCE - 0 >= 199506L) && !(defined(lint) ||
defined(__lint))
extern int *___errno();
#define errno (*(___errno()))
...

And similar on Linux & others I believe. Of course, it _can_ as well be
a global variable...

And in lcc-win32 too. What's the point?

The fact that it calls a function that reads a global variable that
is thread specific (the reson for this) doesn't change the fact
that errno is a global variable.
 
M

matevzb

jacob said:
matevzb a écrit :
And in lcc-win32 too. What's the point?
The point is purely "semantic". You said "it is an ugly global
variable" which may or may not be true. It can be a
function-calling-macro to access an ugly global variable.
The fact that it calls a function that reads a global variable that
is thread specific (the reson for this) doesn't change the fact
that errno is a global variable.
Agreed, except for what was mentioned above. No offense meant. =)
 
K

kuyper

jacob said:
matevzb a écrit :

And in lcc-win32 too. What's the point?

The fact that it calls a function that reads a global variable that
is thread specific (the reson for this) doesn't change the fact
that errno is a global variable.

No, errno is a macro that, for those implementations, expands into a
dereferencing of the pointer value returned by a function call. The
variable referred to by dereferencing that pointer value is not
required to be global, nor is it required to have the name "errno". It
could be dynamically allocated, or a file-scope or even block-scope
static variable. I'm not very familiar with multi-threaded programming
environment, but I'm sure that all three of those are legal
possibilities in a single-threaded environment.

However, your basic point is correct - errno's defined semantics are
such that, at least in a single-threaded environment, it can be
implemented as a global variable. That means that it possesses most of
the design problems that it would have if it were required to be a
global variable.
 
A

Arthur J. O'Dwyer

[fups-to: comp.std.c, comp.compilers.lcc]

Richard Bos a écrit :

The problems of errno are many... You have to avoid forgetting to
set it to zero before calling the function, and it is an ugly global
variable. Why is a result value a bad design? Can you explain?

IMNSHO, errno is awful and should not be used in new code, for the
reasons Jacob mentions. However, Jacob replaces it with a collection of
five different magic numbers that can be returned by just one function;
this solution clearly can't scale!

switch (myfunc()) {
case -5:
case -4:
handle_one(); break;
case -3:
handle_two(); break;
[...]

Would code with this many magic numbers pass /your/ code reviews? A
slightly better idea would be to give them mnemonic names --- perhaps even
reusing the implementation's errno macros (EINVAL, ENOMEM, whatever). This
might require standardizing more of those identifiers; I know only a few
of them are standard, despite the entire E* namespace's being reserved.

So Jacob's solution is bad, but it's the lesser of two evils. OTOH, I'm
not yet convinced there's not a third evil that's lessest! ;)

my $.02,
-Arthur
 
D

David R Tribble

jacob said:
The problems of errno are many... You have to avoid forgetting to
set it to zero before calling the function, and it is an ugly global
variable. Why is a result value a bad design? Can you explain?

Can you guarantee that the function will never return any of
the error values as non-errors? I.e., given that the return code
is signed (which it needs to be because of the error values),
is there a guarantee that the function will never return a
large (unsigned) success value that gets converted into a
small signed value?

Furthermore, if we assume that only values between -1 and,
say, -9 are error values, what happens to our code when we
need to add another error value to the function in the next
revision?

And where are the macros for those magic return values?

Using errno properly is not that difficult, and it works.

-drt
 
D

Douglas A. Gwyn

Hallvard B Furuseth said:
Indeed. Why don't they just set errno though? ...

Guys, it's a *working draft*. There is still time to improve the specs,
but that's not going to happen by you squawking here. Provide
useful comments back to the draft's editor.
 
J

jacob navia

Douglas A. Gwyn a écrit :
Guys, it's a *working draft*. There is still time to improve the specs,
but that's not going to happen by you squawking here. Provide
useful comments back to the draft's editor.
Oooops!

I was supposing that the author(s) read this newsgroup, what may be
untrue. Reading the document there is no obvious hint as to
who edited or who proposed it. In the link that leads to that document
there is the mention:
2006/10/03 Stoughton, Specification for C Library Functions - Part 2:
Dynamic Allocation Functions.

Maybe you know how to contact (Mr or Mrs) Stoughton ?
(E-mail, or address)

Thanks

jacob
 
M

Mark McIntyre

Maybe you know how to contact (Mr or Mrs) Stoughton ?
(E-mail, or address)

STFW.

"Stoughton" (probably Nick) is an ISO/IEC committee member
representing the FSG, so presumably you can contact the WG14 or the
FSG.
--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
 
R

Richard Bos

jacob navia said:
Richard Bos a écrit :

The problems of errno are many... You have to avoid forgetting to
set it to zero before calling the function, and it is an ugly global
variable.

All true. However, it has one great advantage: it is Standard ISO C, and
therefore known to all users and predictable.
Why is a result value a bad design? Can you explain?

_A_ result value is not. Using random negative values for errors and
positive values for non-errors is fragile. It presumes that correct
results will never overflow into negative values, for example. _If_ you
know that this will never happen, that's fine, but this function is
meant as an enhancement to the Standard, not as part of a single program
with predictable input, so it needs to be more solid than most.

For the record: I have nothing against your solution _for a user
function_. For a (meant to become Standard) library function, though, I
strongly suggest using the Standard mechanism for reporting errors.

Richard
 
R

Richard Heathfield

Richard Bos said:

However, [errno] has one great advantage: it is Standard ISO C,

That doesn't mean it is universally supported, however. I know of at least
one otherwise-conforming implementation which doesn't support errno
correctly. Yet another reason for avoiding it completely.
 
P

pete

Richard said:
Richard Bos said:

However, [errno] has one great advantage: it is Standard ISO C,

That doesn't mean it is universally supported, however.
I know of at least
one otherwise-conforming implementation which doesn't support errno
correctly. Yet another reason for avoiding it completely.

I've never like the concept of EDOM.

That a programmer would write code to initialise errno
and check it after a function call, rather than to ensure
that the arguments were in the domain of the function,
seems strange to me.
 
C

CBFalconer

Richard said:
.... snip ..


_A_ result value is not. Using random negative values for errors
and positive values for non-errors is fragile. It presumes that
correct results will never overflow into negative values, for
example. _If_ you know that this will never happen, that's fine,
but this function is meant as an enhancement to the Standard, not
as part of a single program with predictable input, so it needs
to be more solid than most.

For the record: I have nothing against your solution _for a user
function_. For a (meant to become Standard) library function,
though, I strongly suggest using the Standard mechanism for
reporting errors.

Take a look at the error reporting in ggets. It is controlled by
an enum for positive values, and EOF for negative values. No
possibility of overflow (which in itself would be undefined
behaviour) exist. Success is always reported by zero, leaving the
full integer range for various errors. This interfaces easily with
any routine to read as much as is available:

while (!ggets(&lineptr)) processline(lineptr);

and if you want to differentiate between failures you just save the
return value. This is also why ggets doesn't return the line
length. The complications of using ERRNO would be indescribable.
KISS applies. Save the complications for the rare cases.

<http://cbfalconer.home.att/download/>

BTW Jacobs routine has the fault of returning -1 for EOF, which may
or may not agree with the system. This forces detailed reading of
the routine specification, and/or publishing an enom of values for
the various errors, which may in turn lead to name conflicts.
 
D

David R Tribble

Richard Bos said:
However, [errno] has one great advantage: it is Standard ISO C,

Richard said:
That doesn't mean it is universally supported, however. I know of at least
one otherwise-conforming implementation which doesn't support errno
correctly. Yet another reason for avoiding it completely.

Sorry, but I'm not going to stop writing portable code that uses errno
just because one implementation gets it wrong.

-drt
 
R

Richard Heathfield

David R Tribble said:
Richard Bos said:
However, [errno] has one great advantage: it is Standard ISO C,

Richard said:
That doesn't mean it is universally supported, however. I know of at
least one otherwise-conforming implementation which doesn't support errno
correctly. Yet another reason for avoiding it completely.

Sorry, but I'm not going to stop writing portable code that uses errno
just because one implementation gets it wrong.

Understood. But I did precisely that, because I *needed* my stuff to compile
under that implementation (among others).

If you don't have to port to <foo>, there's no need to make your stuff
<foo>-compatible. But if you do, you have no choice. Which is why I don't
use errno at all - and that's a bit of a pest when it comes to robust use
of, say, strtol.
 

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,276
Latest member
Sawatmakal

Latest Threads

Top