In the documents presented in the post Portland meeting
of the C standards comitee http://www.open-std.org/jtc1/sc22/wg14/
there is a document called ISO/IEC WDTR 24731-2,
Specification for Safer C Library Functions —
Part II: Dynamic Allocation Functions
In that document we have:
ssize_t getdelim(char **restrict lineptr,
size_t *restrict n, int delimiter, FILE *stream);
We read:
< quote >
Upon successful completion the getdelim function shall return the number
of characters written into the buffer, including the delimiter character
if one was encountered before EOF. Otherwise it shall return −1.
< end quote >
We come back here to the error analysis problem, a problem that I
have been mentioning since ages and comes again and again. Returning
-1 to indicate "some error occurred but I will not tell you which"
is BAD DESIGN!
This function can have several errors that should be distinguished in
the return value of the function, i.e. there should be other return
values for signaling errors to the user. Lcc-win32 implements this
function and returns:
-5 No memory left for allocating the line
-4 Line pointer points to a buffer but n is <= 0. This is an error in
the incoming arguments.
-3 The n parameter is NULL
-2 The LinePointer parameter is NULL
-1 End of file without any characters read.
This is a much more detailed error reporting, that allows the
user of the function to discriminate between the different error
conditions. It is sad that a document that proposed "safer" functions
doesn't do the error analysis that is an essential part of safer
programming.
Dec 3 '06
61 4011
pete wrote:
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.
Originally, EDOM was intended for math functions, where
an exact test for "within the domain" might be difficult
(consider atan), and also to catch accidents (programming
explicit validity tests before every usage is so tedious,
especially when one expects all usage to be valid, that
you can't rely on users to do it). It would have been
much better to have used a generic nested-exception
handling facility, which allows fine-grained override of
global error-handling strategy. A sort of in-between
approach showed up in the commercial branch of Unix, in
the form of a function named "matherror" for which the
user could substitute his own version.
Richard Heathfield said:
Harald van D?k said:
<snip>
>
>but if you don't mind unspecified output, this works in Borland C++ 5.5 (in C mode):
No time right now - I'll check it as soon as I get home. (After getting my
coat off, making some coffee, ... but you get the idea.)
<sighBetter late than never. Anyway, I've just checked your code in BC5.6
and it works fine. So either they finally fixed this, or I was imagining
things. Which do you reckon? (Don't answer that...)
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999 http://www.cpax.org.uk
email: rjh at the above domain, - www.
Douglas A. Gwyn wrote:
>
Originally, EDOM was intended for math functions, where
an exact test for "within the domain" might be difficult
(consider atan),
Reasonable.
and also to catch accidents (programming
explicit validity tests before every usage is so tedious,
especially when one expects all usage to be valid, that
you can't rely on users to do it).
I doubt that justifies existence of EDOM; that's what we're doing in
C everyday.
--
Jun, Woong (woong at icu.ac.kr)
Samsung Electronics Co., Ltd.
``All opinions expressed are mine, and do not represent
the official opinions of any organization.''
CBFalconer <cb********@yahoo.comwrote:
Richard Bos wrote:
jacob navia <ja***@jacob.remcomp.frwrote:
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.
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.
That's arguably better design, but it's not the design that was used in
the proposed getdelim() specification in the first place. Using EOF as
an in-band error value for that was less than ideal; using -1 through
-5, disregarding possible other values of EOF than -1, is worse.
Richard
Richard Bos a écrit :
>
That's arguably better design, but it's not the design that was used in
the proposed getdelim() specification in the first place. Using EOF as
an in-band error value for that was less than ideal; using -1 through
-5, disregarding possible other values of EOF than -1, is worse.
Richard
No it is not. The result value is a ssize_t, i.e. a signed size_t.
This means that all negative values are free to use as error
values since the valid return values are from zero to INT_MAX.
ssize_t getdelim(char **restrict lineptr,
size_t *restrict n,
int delimiter, FILE *stream);
jacob navia wrote:
Richard Bos a écrit :
>> That's arguably better design, but it's not the design that was used in+ the proposed getdelim() specification in the first place. Using EOF as an in-band error value for that was less than ideal; using -1 through -5, disregarding possible other values of EOF than -1, is worse.
No it is not. The result value is a ssize_t, i.e. a signed size_t.
This means that all negative values are free to use as error
values since the valid return values are from zero to INT_MAX.
ssize_t getdelim(char **restrict lineptr,
size_t *restrict n,
int delimiter, FILE *stream);
There is no guarantee as to the value of EOF, other than that it is
negative. Any mapping into a size_t runs the risk of clashes. Use
an int to return EOF.
--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
CBFalconer <cb********@yahoo.comwrites:
jacob navia wrote:
>Richard Bos a écrit :
>>> That's arguably better design, but it's not the design that was used in+ the proposed getdelim() specification in the first place. Using EOF as an in-band error value for that was less than ideal; using -1 through -5, disregarding possible other values of EOF than -1, is worse.
No it is not. The result value is a ssize_t, i.e. a signed size_t. This means that all negative values are free to use as error values since the valid return values are from zero to INT_MAX.
ssize_t getdelim(char **restrict lineptr, size_t *restrict n, int delimiter, FILE *stream);
There is no guarantee as to the value of EOF, other than that it is
negative. Any mapping into a size_t runs the risk of clashes. Use
an int to return EOF.
You could declare an enumerated type whose constants specify the
various error conditions. The values of the constants wouldn't have
to be consistent from one implementation to another, just their names.
It would be up to the implementer to avoid colliding with the value of
EOF. (EOF is -1 on every implementation I've ever heard of; a
programmer can't safely make that assumption, but an implementer can.)
For example:
enum {
ERROR_MAX = -2,
ERROR_FOO = -2,
ERROR_BAR = -3,
ERROR_BAZ = -4,
ERROR_XYZ = -5,
ERROR_MIN = -5
};
There's no tag for the enumerated type because it's used only to
declare a series of constants.
getdelim() could still return ssize_t (I've lost track, are we
assuming that ssize_t exists?), and it could be used like this:
ssize_t result = getdelim(arg1, arg2, arg3, arg4);
if (result >= 0) {
/* ... */
}
else if (result == EOF) {
/* ... */
}
else if (result >= ERROR_MIN && result <= ERROR_MAX) {
switch(result) {
case ERROR_FOO: /* ... */
/* ... */
default: /* ... */
}
}
This lets you squeeze valid results, EOF, and multiple error codes
into a single return value. It also assumes that losing half the
range of size_t isn't a problem.
I'm not claiming that this is a particularly good approach, just that
it's possible.
--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Keith Thompson <ks***@mib.orgwrites:
You could declare an enumerated type whose constants specify the
various error conditions. The values of the constants wouldn't have
to be consistent from one implementation to another, just their names.
It would be up to the implementer to avoid colliding with the value of
EOF. (EOF is -1 on every implementation I've ever heard of; a
programmer can't safely make that assumption, but an implementer can.)
I think that this kind of dodge would consistently avoid EOF and
positive values:
enum {
MY_ERR_MIN = EOF ^ 0x100,
MY_ERR_FIRSTERR = MY_ERR_MIN,
MY_ERR_SECONDERR,
MY_ERR_ANOTHERERR,
...etc...
MY_ERR_SENTINEL,
MY_ERR_MAX = MY_ERR_SENTINEL - 1
};
--
Ben Pfaff
email: bl*@cs.stanford.edu
web: http://benpfaff.org
Keith Thompson wrote:
CBFalconer <cb********@yahoo.comwrites:
>>jacob navia wrote:
>>>Richard Bos a écrit :
That's arguably better design, but it's not the design that was used in+ the proposed getdelim() specification in the first place. Using EOF as an in-band error value for that was less than ideal; using -1 through -5, disregarding possible other values of EOF than -1, is worse.
No it is not. The result value is a ssize_t, i.e. a signed size_t. This means that all negative values are free to use as error values since the valid return values are from zero to INT_MAX.
ssize_t getdelim(char **restrict lineptr, size_t *restrict n, int delimiter, FILE *stream);
There is no guarantee as to the value of EOF, other than that it is negative. Any mapping into a size_t runs the risk of clashes. Use an int to return EOF.
You could declare an enumerated type whose constants specify the
various error conditions. The values of the constants wouldn't have
to be consistent from one implementation to another, just their names.
It would be up to the implementer to avoid colliding with the value of
EOF. (EOF is -1 on every implementation I've ever heard of; a
programmer can't safely make that assumption, but an implementer can.)
For example:
enum {
ERROR_MAX = -2,
ERROR_FOO = -2,
ERROR_BAR = -3,
ERROR_BAZ = -4,
ERROR_XYZ = -5,
ERROR_MIN = -5
};
There's no tag for the enumerated type because it's used only to
declare a series of constants.
getdelim() could still return ssize_t (I've lost track, are we
assuming that ssize_t exists?), and it could be used like this:
ssize_t result = getdelim(arg1, arg2, arg3, arg4);
if (result >= 0) {
/* ... */
}
else if (result == EOF) {
/* ... */
}
else if (result >= ERROR_MIN && result <= ERROR_MAX) {
switch(result) {
case ERROR_FOO: /* ... */
/* ... */
default: /* ... */
}
}
This lets you squeeze valid results, EOF, and multiple error codes
into a single return value. It also assumes that losing half the
range of size_t isn't a problem.
I'm not claiming that this is a particularly good approach, just that
it's possible.
This looks VERY reasonable. Thanks
jacob
jacob navia <ja***@jacob.remcomp.frwrites:
Keith Thompson wrote:
[...]
>It would be up to the implementer to avoid colliding with the value of EOF. (EOF is -1 on every implementation I've ever heard of; a programmer can't safely make that assumption, but an implementer can.) For example:
[big snip]
This looks VERY reasonable. Thanks
jacob
Um, I have mixed feelings about that. I was trying to create the most
reasonable design given the assumption that you want to squeeze valid
results, EOF, and multiple error conditions into a single return
value. Personally, I don't particularly like the assumption.
--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Ben Pfaff wrote:
I think that this kind of dodge would consistently avoid EOF and
positive values:
enum {
MY_ERR_MIN = EOF ^ 0x100,
MY_ERR_FIRSTERR = MY_ERR_MIN,
MY_ERR_SECONDERR,
MY_ERR_ANOTHERERR,
...etc...
MY_ERR_SENTINEL,
MY_ERR_MAX = MY_ERR_SENTINEL - 1
};
Not if EOF is 0x100. There's also the risk that you might end up with
more than 256 error messages...
--
ais523
ais523 wrote:
Ben Pfaff wrote:
I think that this kind of dodge would consistently avoid EOF and
positive values:
enum {
MY_ERR_MIN = EOF ^ 0x100,
MY_ERR_FIRSTERR = MY_ERR_MIN,
MY_ERR_SECONDERR,
MY_ERR_ANOTHERERR,
...etc...
MY_ERR_SENTINEL,
MY_ERR_MAX = MY_ERR_SENTINEL - 1
};
Not if EOF is 0x100. There's also the risk that you might end up with
-0x100, obviously.
more than 256 error messages...
--
ais523 This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
by: Mr.Tickle |
last post by:
// Run this code and look for his obvious error by the compiler
namespace FlagCheck
{
using System;
enum SomeFlags
{
|
by: rithish |
last post by:
<code>
var dt = new Date(2004, 0, 1);
alert ( dt.getDate() ); // returns proper date
alert ( dt.getUTCFullYear() ); // returns 2003
</code>
Why is this so? Or is that I am missing...
|
by: G Matthew J |
last post by:
interesting "signal vs. noise" blog entry:
http://37signals.com/svn/archives2/whats_wrong_with_ajax.php
|
by: Alok |
last post by:
Hi,
I recently upsized my access database to an ADP project with SQL
backend. However when I did it the import/export specs were not ported
to the new database. Also in the ADP files I am unable...
|
by: Michael B Allen |
last post by:
Is there anything wrong with this macro?
#define randint(a,b) (a)+(((b)-(a)+1)*(float)rand()/RAND_MAX)
If I do randint(10, 0x10000) in a loop it sporatically generates:
Program received...
| |
by: snowweb |
last post by:
I'm creating my first web application in PHP/MySQL, however, when I go to view the database contents, the data has been stored in the wrong columns. I've gone through my insertion code with a fine...
|
by: safak112 |
last post by:
Hi everybody;
I am exporting a table to a new txt file by using MS access 2000. But as you know we can save our export specs, and next time we can call it and can use it once more. But in my...
|
by: Mantorok |
last post by:
What are realistic PC specs for using Visual Studio 2005?
Thanks
Kev
|
by: Grant Edwards |
last post by:
I've got a system where I try to install extensions using
/usr/local/bin/python setup.py install
But, it fails when it tries to use a non-existant compiler path
and specs file. I suspect it's...
|
by: marktang |
last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
|
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
| |
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers,...
|
by: Hystou |
last post by:
Overview:
Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
|
by: conductexam |
last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
|
by: TSSRALBI |
last post by:
Hello
I'm a network technician in training and I need your help.
I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs.
The...
|
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
|
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
| |
by: bsmnconsultancy |
last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...
| |