Email List: Xaustin-group-lX
[All Lists]

Re: [1003.1(2008)/Issue 7 0000177]: mismatch between example description

To: austin-group-l@xxxxxxxxxxxxx
Subject: Re: [1003.1(2008)/Issue 7 0000177]: mismatch between example descriptionand code
From: shwaresyst@xxxxxxx
Date: Sun, 08 Nov 2009 16:19:40 -0500
References: <20091106204046.Q1687@xxxxxx>
Yes, that was a typo where I forgot the extra '=' in the conditional.

if (line_max == LONG_MAX) return EOVERFLOW;

was the intent. To be safest you'd have to query the system for the largest allocation malloc() supports right at that time and compare it to the return value of sysconf(), and make sure the value is at least 1 before incrementing so fgets() doesn't become a no-op. The simple test used here, whether LONG_MAX, SIZE_MAX, or some other static value is most appropriate, just illustrates that the return value can not be relied on to be a sensible value, but still might match the basic criteria required in <limits.h>. I consider this unfortunate, but not particularly avoidable nor do I consider it a defect of the standard.

The resources needed to construct a reliable heuristic or analytic routine that returns a viable minimax value can be considerable, in terms of testing time and having multiple hardware configurations available to conduct the tests on, and as such some developers without those resources might use an extravagant value to at least be nominally compliant. On systems with even more extravagant resources available, those might even be plausibly usable. For example, on a system with 16GB of RAM, a malloc(LONG_MAX) of 2GB might be expected to succeed.

As to sysconf() being able to return -1 in a blanket manner for all input values defined, is a formal interpretation request required to reconcile it with <limits.h>?

This directly conflicts with the statements in <limits.h> that all values in that section shall have as their minimums the _POSIX_* and _POSIX2_* equivalent values. As such, since definite explicit values are defined by the standard, the allowing clause of the blanket statement fails, as I see it, and indefinite is not permitted. Otherwise an application would have to view such a value as the implementation's developers trying to undefine that limit in favor of infinite, or saying for that hardware configuration a suitable calculation routine wasn't implemented, for whatever reason, and as such it's a "you always have to figure out your own limit" flag, yet one of the purposes of sysconf() is so applications shouldn't need to do this.

Indefinite would be legitimate, as I read it, for values where consensus could not be reached on an arbitrary value or a suitable routine has calculated system resources are allocated so much that not even the default minimums are reliable until enough resources are freed. The only potentially reliable values an application can assume in that circumstance are the minimums that the affected interfaces require to get any work done, e.g. for fgets() N would have to be 2 if sysconf() is allowed to return -1 for _SC_LINE_MAX, and even then the implementation is not guaranteeing that it will succeed, just that it's the one most likely to work.

That's all,
Mark

-----Original Message-----
From: Bruce Evans <brde@xxxxxx>
To: Austin Group Bug Tracker <noreply@xxxxxx>
Cc: austin-group-l@xxxxxx
Sent: Fri, Nov 6, 2009 5:11 am
Subject: Re: [1003.1(2008)/Issue 7 0000177]: mismatch between example description and code









On Thu, 5 Nov 2009, Austin Group Bug Tracker wrote:


dynamic allocation example of fgets(), per discussion:

...

int f(FILE *fp)

{

 long line_max; /* used to avoid multiple sysconf() calls */

 char *line; /* the buffer */

/* declare other variables function needs */



/* get implementation instance's max expectable line length */

 line_max = sysconf(_SC_LINE_MAX);

/* account as practical for fgets() appending a NULL char */

 if (line_max = LONG_MAX) return EOVERFLOW;

This assigns to line_max instead of testing it, and thus always returns

EOVERFLOW.


 line_max ++;



 line = malloc(line_max); /* get the buffer space */

Overflow can still occur here (iff LONG_MAX > SIZE_MAX). So the above

should be something like


if (line_max == LONG_MAX || line_max >= SIZE_MAX)

return EOVERFLOW;


if you want the example to be technically correct. It still wouldn't

actually work on systems that set {LINE_MAX} + 1 to huge value (too large

to malloc()) in an attempt to force applications to support arbitrarily

long lines.


Bruce






<Prev in Thread] Current Thread [Next in Thread>