Hey,
I was reading C99 Rationale, and it has the following two QUIET CHANGE
paragraphs:
6.5.3.4: "With the introduction of the long long and extended integer
types, the sizeof operator may yield a value that exceeds the range
of an unsigned long."
6.5.6: "With the introduction of the long long and extended integer
types, the subtraction of pointers may return a value that exceeds the
range of a long."
Was it required by C89 that result of sizeof() fits into unsigned long,
and that pointer subtraction result fits into long? If yes, then MS
Win64 implementation is not C89-conforming (while sizeof case may be
arguable, I guess, we certainly can ask to malloc more than ULONG_MAX
bytes, and get pointer arithmetics which needs more than (unsigned)
long). If no, why these two paragraphs, if programs which relied on long
being big enough were already broken?
Yevgen 73 7235
Yevgen Muntyan wrote On 03/14/07 14:26,:
Hey,
I was reading C99 Rationale, and it has the following two QUIET CHANGE
paragraphs:
6.5.3.4: "With the introduction of the long long and extended integer
types, the sizeof operator may yield a value that exceeds the range
of an unsigned long."
6.5.6: "With the introduction of the long long and extended integer
types, the subtraction of pointers may return a value that exceeds the
range of a long."
Was it required by C89 that result of sizeof() fits into unsigned long,
and that pointer subtraction result fits into long?
"Yes" and "Almost," respectively. C89 offered a fixed
set of integer types, of which {,un}signed long was the widest.
The implementation was free to provide additional types that
behaved like integers, but they were not "integer types" as
C89 defined them. C89 also required that size_t and ptrdiff_t
be aliases for "integer types," so they could not be wider than
long. If an implementation offered wider types, they were not
"integer types" and hence were not candidates for size_t and
ptrdiff_t.
On machines whose longs are the same width as their pointers
(more generally, no wider than their pointers), this means that
ptrdiff_t cannot be wide enough to express the result of all
pointer subtractions. An easy example:
char *p = malloc(LONG_MAX + 2u); /* assume success */
char *q = p + LONG_MAX + 2u;
ptrdiff_t delta = q - p;
We will now have p < q but (probably) delta < 0.
If yes, then MS
Win64 implementation is not C89-conforming (while sizeof case may be
arguable, I guess, we certainly can ask to malloc more than ULONG_MAX
bytes, and get pointer arithmetics which needs more than (unsigned)
long). If no, why these two paragraphs, if programs which relied on long
being big enough were already broken?
I don't know MS' Win64 implementation well enough to comment
on whether it's broken or not. As for programs that assumed
size_t and ptrdiff_t were no wider than long, no: They were not
broken under C89's rules, because C89 implied the truth of the
assumption. C99 changed the rules, allowing the implementation-
defined "exotic" types to be counted among the "integer types,"
and this change could break some programs that relied on the old
rule. Hence the "Quiet Change" warnings.
-- Er*********@sun.com
Eric Sosman wrote:
Yevgen Muntyan wrote On 03/14/07 14:26,:
>Hey,
I was reading C99 Rationale, and it has the following two QUIET CHANGE paragraphs:
6.5.3.4: "With the introduction of the long long and extended integer types, the sizeof operator may yield a value that exceeds the range of an unsigned long."
6.5.6: "With the introduction of the long long and extended integer types, the subtraction of pointers may return a value that exceeds the range of a long."
Was it required by C89 that result of sizeof() fits into unsigned long, and that pointer subtraction result fits into long?
"Yes" and "Almost," respectively. C89 offered a fixed
set of integer types, of which {,un}signed long was the widest.
The implementation was free to provide additional types that
behaved like integers, but they were not "integer types" as
C89 defined them. C89 also required that size_t and ptrdiff_t
be aliases for "integer types," so they could not be wider than
long. If an implementation offered wider types, they were not
"integer types" and hence were not candidates for size_t and
ptrdiff_t.
On machines whose longs are the same width as their pointers
(more generally, no wider than their pointers), this means that
ptrdiff_t cannot be wide enough to express the result of all
pointer subtractions. An easy example:
char *p = malloc(LONG_MAX + 2u); /* assume success */
char *q = p + LONG_MAX + 2u;
ptrdiff_t delta = q - p;
We will now have p < q but (probably) delta < 0.
>If yes, then MS Win64 implementation is not C89-conforming (while sizeof case may be arguable, I guess, we certainly can ask to malloc more than ULONG_MAX bytes, and get pointer arithmetics which needs more than (unsigned) long). If no, why these two paragraphs, if programs which relied on long being big enough were already broken?
I don't know MS' Win64 implementation well enough to comment
on whether it's broken or not.
It has 32-bit long, same as int, and naturally 64-bit size_t.
As for programs that assumed
size_t and ptrdiff_t were no wider than long, no: They were not
broken under C89's rules, because C89 implied the truth of the
assumption.
Then these programs may be broken on Win64, right? Say, this code:
void do_something (void *buf, unsigned long len)
{
memset (buf, 1, len);
}
int main (void)
{
size_t i;
size_t size = BIG_NUMBER;
char *p = malloc (size);
if (p)
{
do_something (p, size);
assert (p[size-1]);
}
return 0;
}
BIG_NUMBER can be defined as some square root of SIZE_MAX+1 multiplied
by two or something, so we don't need to invent functions which get
us a big buffer. I guess MS estimated somehow how much of their code
uses long as 32-bit int, and decided it's more than code which uses
unsigned long as size_t. Anyway, is MS Win64 implementation not
C89-conforming (it's an important thing, isn't it)? Or I do miss
something?
Thanks,
Yevgen
Yevgen Muntyan wrote On 03/14/07 15:14,:
Eric Sosman wrote:
>>Yevgen Muntyan wrote On 03/14/07 14:26,:
>>>[...] Was it required by C89 that result of sizeof() fits into unsigned long, and that pointer subtraction result fits into long? [...] If yes, then MS Win64 implementation is not C89-conforming (while sizeof case may be arguable, I guess, we certainly can ask to malloc more than ULONG_MAX bytes, and get pointer arithmetics which needs more than (unsigned) long). [...]
I don't know MS' Win64 implementation well enough to comment on whether it's broken or not.
It has 32-bit long, same as int, and naturally 64-bit size_t.
If size_t is wider than long, the implementation cannot
conform to C89. It could, however, conform to C99, with
size_t being as wide as long long or as some other wide type.
One of the (many) things I don't know about MS Win64 is what
standards it claims to conform to.
>>As for programs that assumed size_t and ptrdiff_t were no wider than long, no: They were not broken under C89's rules, because C89 implied the truth of the assumption.
Then these programs may be broken on Win64, right? Say, this code:
void do_something (void *buf, unsigned long len)
{
memset (buf, 1, len);
}
int main (void)
{
size_t i;
size_t size = BIG_NUMBER;
char *p = malloc (size);
if (p)
{
do_something (p, size);
assert (p[size-1]);
}
return 0;
}
If malloc() succeeds, this program works under C89 but
might not work on a C99 implementation.
[...] Anyway, is MS Win64 implementation not
C89-conforming (it's an important thing, isn't it)? Or I do miss
something?
From your description, it cannot be a conforming C89
implementation. Is that important? Well, to whom?
-- Er*********@sun.com
Eric Sosman wrote:
Yevgen Muntyan wrote On 03/14/07 15:14,:
>Eric Sosman wrote:
>>Yevgen Muntyan wrote On 03/14/07 14:26,: [...] Was it required by C89 that result of sizeof() fits into unsigned long, and that pointer subtraction result fits into long? [...] If yes, then MS Win64 implementation is not C89-conforming (while sizeof case may be arguable, I guess, we certainly can ask to malloc more than ULONG_MAX bytes, and get pointer arithmetics which needs more than (unsigned) long). [...] I don't know MS' Win64 implementation well enough to comment on whether it's broken or not.
It has 32-bit long, same as int, and naturally 64-bit size_t.
If size_t is wider than long, the implementation cannot
conform to C89. It could, however, conform to C99, with
size_t being as wide as long long or as some other wide type.
One of the (many) things I don't know about MS Win64 is what
standards it claims to conform to.
It claims conformance to C90. It does not conform to C99.
....
>[...] Anyway, is MS Win64 implementation not C89-conforming (it's an important thing, isn't it)? Or I do miss something?
From your description, it cannot be a conforming C89
implementation. Is that important? Well, to whom?
Well, to people who want to write code which would work on win64.
Yevgen
Yevgen Muntyan wrote On 03/14/07 15:57,:
Eric Sosman wrote:
>> If size_t is wider than long, the implementation cannot conform to C89. [...]
It claims conformance to C90. It does not conform to C99.
In that case, the claim is incorrect, and testably so:
size_t u = -1;
unsigned long v = u;
assert (u == v);
>>>[...] Anyway, is MS Win64 implementation not C89-conforming (it's an important thing, isn't it)? Or I do miss something?
From your description, it cannot be a conforming C89 implementation. Is that important? Well, to whom?
Well, to people who want to write code which would work on win64.
Observe that this nonconformance only affects code that
does any of
- Type-punning via unions or pointers to access a size_t
object as an unsigned long or vice versa (or similar punning
between ptrdiff_t and signed long). Such code is broken already
under all versions of the Standard, so it doesn't bother me if
MS causes additional breakage.
- Computing sizes ULONG_MAX bytes (>= 4GB, in this case)
and converting them to unsigned long. First, you'd need to
have a reason to compute such large sizes; all right, on a
64-bit system I'll grant that such reasons may arise. But
then you'd need to write unsigned long instead of size_t to
get into trouble; why would you do that?
- To answer the question, you might do that to print the
size_t value using "%lu" or something of the kind. In this
case, you could get the wrong answer printed, which might or
might not affect the behavior of the rest of the program. As
far as I can imagine, this is the only case you need to worry
about, the only case in "legitimate" code where the fact that
size_t is wider than unsigned long could cause trouble. Be
on your guard!
-- Er*********@sun.com
Yevgen Muntyan <mu****************@tamu.eduwrites:
Eric Sosman wrote:
[...]
> I don't know MS' Win64 implementation well enough to comment on whether it's broken or not.
It has 32-bit long, same as int, and naturally 64-bit size_t.
How is size_t defined? Does the implementation provide an "unsigned
long long" type and make size_t an alias for that? Or does it use
some non-standard syntax for its 64-bit types?
--
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."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Eric Sosman wrote:
Yevgen Muntyan wrote On 03/14/07 15:57,:
>Eric Sosman wrote:
>> If size_t is wider than long, the implementation cannot conform to C89. [...]
It claims conformance to C90. It does not conform to C99.
In that case, the claim is incorrect, and testably so:
size_t u = -1;
unsigned long v = u;
assert (u == v);
>>>[...] Anyway, is MS Win64 implementation not C89-conforming (it's an important thing, isn't it)? Or I do miss something? From your description, it cannot be a conforming C89 implementation. Is that important? Well, to whom?
Well, to people who want to write code which would work on win64.
Observe that this nonconformance only affects code that
does any of
- Type-punning ...
- Computing sizes ULONG_MAX bytes (>= 4GB, in this case)
and converting them to unsigned long. First, you'd need to
have a reason to compute such large sizes; all right, on a
64-bit system I'll grant that such reasons may arise. But
then you'd need to write unsigned long instead of size_t to
get into trouble; why would you do that?
Answer to "why" may be wrong, but it won't change much if it's
already done. There is lot of code which assumes long
is big enough, and one must be aware of it (it's a real issue,
with real software).
There is more important thing to it. This single non-conformance
is simple: use appropriate types and you're good. But if MS broke
this thing (which breaks code, i.e. it's not some academic issue),
then what else is broken? It's a psychological issue (paranoia?).
- To answer the question, you might do that to print the
size_t value using "%lu" or something of the kind. In this
case, you could get the wrong answer printed, which might or
might not affect the behavior of the rest of the program. As
far as I can imagine, this is the only case you need to worry
about, the only case in "legitimate" code where the fact that
size_t is wider than unsigned long could cause trouble.
You're saying it's legitimate. But how is casting size_t
to unsigned long more legitimate than
int process_some_data (char *data, unsigned long len);
Yevgen
On Wed, 14 Mar 2007 18:26:50 GMT, Yevgen Muntyan
<mu****************@tamu.eduwrote in comp.lang.c:
Hey,
I was reading C99 Rationale, and it has the following two QUIET CHANGE
paragraphs:
6.5.3.4: "With the introduction of the long long and extended integer
types, the sizeof operator may yield a value that exceeds the range
of an unsigned long."
6.5.6: "With the introduction of the long long and extended integer
types, the subtraction of pointers may return a value that exceeds the
range of a long."
Was it required by C89 that result of sizeof() fits into unsigned long,
and that pointer subtraction result fits into long? If yes, then MS
Win64 implementation is not C89-conforming (while sizeof case may be
arguable, I guess, we certainly can ask to malloc more than ULONG_MAX
bytes, and get pointer arithmetics which needs more than (unsigned)
long). If no, why these two paragraphs, if programs which relied on long
being big enough were already broken?
Yevgen
What do you mean by "already broken"? Neither 64-bit Windows, nor the
AMD 64-bit extension to the x86 instruction set, existed before the
C99 standard.
--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Keith Thompson wrote:
Yevgen Muntyan <mu****************@tamu.eduwrites:
>Eric Sosman wrote:
[...]
>> I don't know MS' Win64 implementation well enough to comment on whether it's broken or not.
It has 32-bit long, same as int, and naturally 64-bit size_t.
How is size_t defined? Does the implementation provide an "unsigned
long long" type and make size_t an alias for that? Or does it use
some non-standard syntax for its 64-bit types?
It doesn't have long long, it has builtin __int64, and
typedef __int64 intptr_t;
typedef unsigned __int64 uintptr_t;
typedef __int64 ptrdiff_t;
typedef unsigned __int64 size_t;
Yevgen
Jack Klein wrote:
On Wed, 14 Mar 2007 18:26:50 GMT, Yevgen Muntyan
<mu****************@tamu.eduwrote in comp.lang.c:
>Hey,
I was reading C99 Rationale, and it has the following two QUIET CHANGE paragraphs:
6.5.3.4: "With the introduction of the long long and extended integer types, the sizeof operator may yield a value that exceeds the range of an unsigned long."
6.5.6: "With the introduction of the long long and extended integer types, the subtraction of pointers may return a value that exceeds the range of a long."
Was it required by C89 that result of sizeof() fits into unsigned long, and that pointer subtraction result fits into long? If yes, then MS Win64 implementation is not C89-conforming (while sizeof case may be arguable, I guess, we certainly can ask to malloc more than ULONG_MAX bytes, and get pointer arithmetics which needs more than (unsigned) long). If no, why these two paragraphs, if programs which relied on long being big enough were already broken?
Yevgen
What do you mean by "already broken"? Neither 64-bit Windows, nor the
AMD 64-bit extension to the x86 instruction set, existed before the
C99 standard.
*If* Win64 is C90-conforming, then long smaller than size_t is fine,
then a program which uses unsigned long instead of size_t is broken
as far as C90 is concerned (of course it depends on the usage of
those types), so C99 doesn't need to say this is a quiet change.
Yevgen
Yevgen Muntyan <mu****************@tamu.eduwrote:
Eric Sosman wrote:
- To answer the question, you might do that to print the
size_t value using "%lu" or something of the kind. In this
case, you could get the wrong answer printed, which might or
might not affect the behavior of the rest of the program. As
far as I can imagine, this is the only case you need to worry
about, the only case in "legitimate" code where the fact that
size_t is wider than unsigned long could cause trouble.
You're saying it's legitimate.
Well, he says it's "legitimate". In this case, the scare quotes are
important. It's not more or less legal than other cases; but in this
case, it's inevitable, while in other cases, it can be avoided.
But how is casting size_t to unsigned long more legitimate than
int process_some_data (char *data, unsigned long len);
In this case, you could easily make len a size_t instead. Making it an
unsigned long instead is legal C90, but relying on this legality is
perhaps not a good idea, and making it a size_t means you get a
declaration which is more self-documenting for the cost, not of more,
but even of _less_ typing, which patently _is_ a good idea.
In the case of printf(), there's nothing you can easily do in C90 to
avoid having to cast a size_t to an unsigned long. C99 has "%zu", but
that's no help in C90, which does not.
Therefore, assuming a size_t is no larger than an unsigned long is
_legal_ in all cases in C90; but you only have _good reason_ for doing
so in the printf() case.
Richard
Richard Bos wrote:
Yevgen Muntyan <mu****************@tamu.eduwrote:
>Eric Sosman wrote:
>> - To answer the question, you might do that to print the size_t value using "%lu" or something of the kind. In this case, you could get the wrong answer printed, which might or might not affect the behavior of the rest of the program. As far as I can imagine, this is the only case you need to worry about, the only case in "legitimate" code where the fact that size_t is wider than unsigned long could cause trouble.
You're saying it's legitimate.
Well, he says it's "legitimate". In this case, the scare quotes are
important. It's not more or less legal than other cases; but in this
case, it's inevitable, while in other cases, it can be avoided.
>But how is casting size_t to unsigned long more legitimate than
int process_some_data (char *data, unsigned long len);
In this case, you could easily make len a size_t instead.
*If* I can change the code. It's why I was confused: I can't imagine
why I would print a size_t value using unsigned long on Win64 platform,
but I can easily imagine how I use code which uses long instead
of ssize_t and unsigned long instead of size_t. Thanks for
clarification.
Making it an
unsigned long instead is legal C90, but relying on this legality is
perhaps not a good idea, and making it a size_t means you get a
declaration which is more self-documenting for the cost, not of more,
but even of _less_ typing, which patently _is_ a good idea.
By the way, it seems that some people avoid #includ'ing headers like
stddef.h in library headers due to bugs in C implementations
or for some other obscure reasons. I'd think it adds to this
issue: you can use long for free, it's builtin, but to get
size_t you need an extra header.
Yevgen
Yevgen Muntyan <mu****************@tamu.eduwrote:
Richard Bos wrote:
Yevgen Muntyan <mu****************@tamu.eduwrote:
But how is casting size_t to unsigned long more legitimate than
int process_some_data (char *data, unsigned long len);
In this case, you could easily make len a size_t instead.
*If* I can change the code.
If _you_ can't change the code, I would advise not to worry about
whether the ideas expressed in it are legitimate or not; leave that to
the people who did design and do maintain it.
By the way, it seems that some people avoid #includ'ing headers like
stddef.h in library headers due to bugs in C implementations
or for some other obscure reasons. I'd think it adds to this
issue: you can use long for free, it's builtin, but to get
size_t you need an extra header.
Given that size_t is also #defined in <stdio.h>, <stdlib.hand
<string.h>, probably the three most #included headers, without which I
can hardly imagine a useful ISO C program of any reasonable size, as
well as in <time.hand <wchar.h>, IMO people who do this should do a
reality check.
Richard
Richard Bos wrote:
Yevgen Muntyan <mu****************@tamu.eduwrote:
>Richard Bos wrote:
>>Yevgen Muntyan <mu****************@tamu.eduwrote:
But how is casting size_t to unsigned long more legitimate than
int process_some_data (char *data, unsigned long len); In this case, you could easily make len a size_t instead.
*If* I can change the code.
If _you_ can't change the code, I would advise not to worry about
whether the ideas expressed in it are legitimate or not; leave that to
the people who did design and do maintain it.
That's good and everything, but doesn't always work on practice
unfortunately. If I happen to use some library which uses long instead
of ssize_t, and if I happen to get a dll of that library, I have a
problem. This Win64 thing is funny, because no other 'popular' system
has small long type. Good or bad, but lot of useful software is written
under many assumptions like 8-bit bytes, ASCII, long >= size_t. Simply
ignoring it won't always work since you might actually need that
software (you know, libraries which have useful stuff).
>By the way, it seems that some people avoid #includ'ing headers like stddef.h in library headers due to bugs in C implementations or for some other obscure reasons. I'd think it adds to this issue: you can use long for free, it's builtin, but to get size_t you need an extra header.
Given that size_t is also #defined in <stdio.h>, <stdlib.hand
<string.h>, probably the three most #included headers, without which I
can hardly imagine a useful ISO C program of any reasonable size, as
well as in <time.hand <wchar.h>, IMO people who do this should do a
reality check.
Perhaps. Or maybe it's because many vendors put lot of non-standard
stuff into standard headers. Say, if you #include <string.hand
do not #define _GNU_SOURCE with glibc, then you don't get strndup()
declaration. But then library (not the C library) may not mandate
what you get and what you don't from the C library. So it would
need to document its headers include <string.h>, <foo.h>, and whatnot.
And then it must maintain that forever. Don't know, playing devil
advocate here.
Yevgen
Yevgen Muntyan wrote:
Richard Bos wrote:
>Yevgen Muntyan <mu****************@tamu.eduwrote:
>>Richard Bos wrote: Yevgen Muntyan <mu****************@tamu.eduwrote:
But how is casting size_t to unsigned long more legitimate than > int process_some_data (char *data, unsigned long len); In this case, you could easily make len a size_t instead. *If* I can change the code.
If _you_ can't change the code, I would advise not to worry about whether the ideas expressed in it are legitimate or not; leave that to the people who did design and do maintain it.
That's good and everything, but doesn't always work on practice
unfortunately. If I happen to use some library which uses long instead
of ssize_t, and if I happen to get a dll of that library, I have a
problem.
Yes, indeed. Your problem is that you are using a library
written by somebody who didn't understand C, or who chose to be
deliberately perverse in the way he used it. When the library
writer is hostile or incompetent, you certainly have a problem.
This Win64 thing is funny, because no other 'popular' system
has small long type. Good or bad, but lot of useful software is written
under many assumptions like 8-bit bytes, ASCII, long >= size_t. Simply
ignoring it won't always work since you might actually need that
software (you know, libraries which have useful stuff).
Libraries that have useful stuff *and* for which no practical
alternatives exist *and* were written by incompetents or hostiles.
Do you have a specific library in mind, or are you "just
supposing?" If the latter, drop it until the situation actually
arises. If the former, please tell us about it so we'll be warned
not to use that organization's products.
>>By the way, it seems that some people avoid #includ'ing headers like stddef.h in library headers due to bugs in C implementations or for some other obscure reasons. I'd think it adds to this issue: you can use long for free, it's builtin, but to get size_t you need an extra header.
Given that size_t is also #defined in <stdio.h>, <stdlib.hand <string.h>, probably the three most #included headers, without which I can hardly imagine a useful ISO C program of any reasonable size, as well as in <time.hand <wchar.h>, IMO people who do this should do a reality check.
Perhaps. Or maybe it's because many vendors put lot of non-standard
stuff into standard headers. Say, if you #include <string.hand
do not #define _GNU_SOURCE with glibc, then you don't get strndup()
declaration. But then library (not the C library) may not mandate
what you get and what you don't from the C library. So it would
need to document its headers include <string.h>, <foo.h>, and whatnot.
And then it must maintain that forever. Don't know, playing devil
advocate here.
You're playing something, yes, but I don't recognize the tune.
Proposition: There is *no* reason to use unsigned long instead
of size_t. None. Nada. Zero. Zip. Nulla. Every module that
performs I/O includes <stdio.hand has size_t defined; every
module that works with strings includes <string.hand has size_t
defined; every module that calls malloc() includes <stdlib.hand
has size_t defined. The definitions of size_t are so rampant in
the standard headers that it is almost as universal as a keyword.
The excuse "I don't want to include standard headers because they
might be broken" is hopelessly fallacious: If you don't trust the
headers, why would you trust the library? Do you provide a mian()
function just in case the implementation has a spelling error?
As for standard headers providing non-Standard definitions:
First, there are identifiers that are reserved for future use,
meaning that the standard headers are free to define them if
they so choose. You are not allowed to use `isosceles' as an
identifier with external linkage, and if you do use it you are at
fault and not the headers. Second, if you define reserved identifiers
like _GNU_SOURCE you invoke undefined behavior. You may *want* the
undefined behavior, but you can't ask the Standard to bless your
perverted desires. SAFUYOYO.
--
Eric Sosman es*****@acm-dot-org.invalid
Eric Sosman wrote:
Yevgen Muntyan wrote:
>Richard Bos wrote:
>>Yevgen Muntyan <mu****************@tamu.eduwrote:
Richard Bos wrote: Yevgen Muntyan <mu****************@tamu.eduwrote: > >But how is casting size_t to unsigned long more legitimate than >> >int process_some_data (char *data, unsigned long len); In this case, you could easily make len a size_t instead. *If* I can change the code.
If _you_ can't change the code, I would advise not to worry about whether the ideas expressed in it are legitimate or not; leave that to the people who did design and do maintain it.
That's good and everything, but doesn't always work on practice unfortunately. If I happen to use some library which uses long instead of ssize_t, and if I happen to get a dll of that library, I have a problem.
Yes, indeed. Your problem is that you are using a library
written by somebody who didn't understand C, or who chose to be
deliberately perverse in the way he used it. When the library
writer is hostile or incompetent, you certainly have a problem.
Well, I'd choose lighter words than "somebody who didn't
understand C" and "incompetent", but it won't change a thing of course.
Thing is: there is a problem which doesn't exist on sane systems
which use sensible types but which exists on Win64. Why it exists
is another problem.
>This Win64 thing is funny, because no other 'popular' system has small long type. Good or bad, but lot of useful software is written under many assumptions like 8-bit bytes, ASCII, long >= size_t. Simply ignoring it won't always work since you might actually need that software (you know, libraries which have useful stuff).
Libraries that have useful stuff *and* for which no practical
alternatives exist *and* were written by incompetents or hostiles.
It's surely the easiest to walk a problem around by calling others
incompetent, especially if it's not your problem.
Do you have a specific library in mind, or are you "just
supposing?" If the latter, drop it until the situation actually
arises. If the former, please tell us about it so we'll be warned
not to use that organization's products.
I do have a specific library in mind, indeed. It's not written by me
or my friends or relatives. It's a widely used and indeed useful
library.
>>>By the way, it seems that some people avoid #includ'ing headers like stddef.h in library headers due to bugs in C implementations or for some other obscure reasons. I'd think it adds to this issue: you can use long for free, it's builtin, but to get size_t you need an extra header.
Given that size_t is also #defined in <stdio.h>, <stdlib.hand <string.h>, probably the three most #included headers, without which I can hardly imagine a useful ISO C program of any reasonable size, as well as in <time.hand <wchar.h>, IMO people who do this should do a reality check.
Perhaps. Or maybe it's because many vendors put lot of non-standard stuff into standard headers. Say, if you #include <string.hand do not #define _GNU_SOURCE with glibc, then you don't get strndup() declaration. But then library (not the C library) may not mandate what you get and what you don't from the C library. So it would need to document its headers include <string.h>, <foo.h>, and whatnot. And then it must maintain that forever. Don't know, playing devil advocate here.
You're playing something, yes, but I don't recognize the tune.
Proposition: There is *no* reason to use unsigned long instead
of size_t. None. Nada. Zero. Zip. Nulla.
I know none, this is true. You seem to know none. You sure there
*isn't* one?
Every module that
performs I/O includes <stdio.hand has size_t defined;
Unless this module use third-party I/O routines, or uses things like
open/write. I.e. no, not every.
every
module that works with strings includes <string.hand has size_t
defined;
If it's C strings, then that's probably true.
every module that calls malloc() includes <stdlib.hand
has size_t defined.
Yes, if a module calls malloc() then it needs to use stdlib.h. But
not every module calls malloc() to allocate memory. Some call
third-party routines which use unsigned long instead of size_t ;)
Anyway, these three examples are examples of why *user* would
use the standard headers. The library itself may not need them.
Now, it may be important for the user how he uses the standard
headers: what he #define's or in what order he uses the headers,
or whatever. Library has no business in that.
Now, if it's true that one single standard header ever caused
problems, then library developers have really good reason to avoid
standard headers altogether.
The excuse "I don't want to include standard headers because they
might be broken" is hopelessly fallacious: If you don't trust the
headers, why would you trust the library?
I, user, may know that on my FooBar-10.7 I need to sit then
jump three times to use some standard header; I can perform
those exercises when writing my program. If a library makes me a
"favor" and uses the header prior to my jumps, then it does a
wrong thing.
Somehow you started talking like I am saying "I don't want to
use standard headers in my program". Nope.
Do you provide a mian()
function just in case the implementation has a spelling error?
Ever heard of WinMain() thing? No, I don't provide mian() function.
I also don't eat spoons, and I don't fly.
As for standard headers providing non-Standard definitions:
First, there are identifiers that are reserved for future use,
meaning that the standard headers are free to define them if
they so choose. You are not allowed to use `isosceles' as an
identifier with external linkage, and if you do use it you are at
fault and not the headers.
Good or bad, but:
NAME
strdup, strndup, strdupa, strndupa - duplicate a string
SYNOPSIS
#define _GNU_SOURCE
#include <string.h>
char *strndup(const char *s, size_t n);
It's not (other) library developers business how user is going
to use strndup, it's personal matter between user and his C
library.
Second, if you define reserved identifiers
like _GNU_SOURCE you invoke undefined behavior. You may *want* the
undefined behavior,
See above, SYNOPSIS section.
but you can't ask the Standard to bless your
perverted desires. SAFUYOYO.
Am I asking the standard about something?
Yevgen
Eric Sosman wrote:
Yevgen Muntyan wrote:
>Richard Bos wrote:
>>Yevgen Muntyan <mu****************@tamu.eduwrote:
Richard Bos wrote: Yevgen Muntyan <mu****************@tamu.eduwrote: > >But how is casting size_t to unsigned long more legitimate than >> >int process_some_data (char *data, unsigned long len); In this case, you could easily make len a size_t instead. *If* I can change the code.
If _you_ can't change the code, I would advise not to worry about whether the ideas expressed in it are legitimate or not; leave that to the people who did design and do maintain it.
That's good and everything, but doesn't always work on practice unfortunately. If I happen to use some library which uses long instead of ssize_t, and if I happen to get a dll of that library, I have a problem.
Yes, indeed. Your problem is that you are using a library
written by somebody who didn't understand C, or who chose to be
deliberately perverse in the way he used it. When the library
writer is hostile or incompetent, you certainly have a problem.
Forgot to mention another evil thing the library does: it uses void*
for function pointers. I wonder if it's caused by hostility or
incompetence.
Yevgen Muntyan wrote:
Eric Sosman wrote:
>Yevgen Muntyan wrote:
>>This Win64 thing is funny, because no other 'popular' system has small long type. Good or bad, but lot of useful software is written under many assumptions like 8-bit bytes, ASCII, long >= size_t. Simply ignoring it won't always work since you might actually need that software (you know, libraries which have useful stuff).
Do you have a specific library in mind, or are you "just supposing?" If the latter, drop it until the situation actually arises. If the former, please tell us about it so we'll be warned not to use that organization's products.
I do have a specific library in mind, indeed. It's not written by me
or my friends or relatives. It's a widely used and indeed useful
library.
... which you have not named, to warn us away from it.
> Proposition: There is *no* reason to use unsigned long instead of size_t. None. Nada. Zero. Zip. Nulla.
I know none, this is true. You seem to know none. You sure there
*isn't* one?
I offered the remark as a "proposition," thus inviting
a counter-example. Got one?
>Every module that performs I/O includes <stdio.hand has size_t defined;
Unless this module use third-party I/O routines, or uses things like
open/write. I.e. no, not every.
Yes, "every" -- unless you've decided to stray outside the
bounds of Standard C. There are good reasons for such strayings,
but you can hardly blame the consequences on the Standard headers.
Anyway, these three examples are examples of why *user* would
use the standard headers. The library itself may not need them.
Now, it may be important for the user how he uses the standard
headers: what he #define's or in what order he uses the headers,
or whatever. Library has no business in that.
Again, I'd be interested to learn the name of this perverse
library you keep alluding to.
Proposition: A library that deals in object sizes but uses
unsigned long instead of size_t to describe them is perverse.
Counter-example?
Now, if it's true that one single standard header ever caused
problems, then library developers have really good reason to avoid
standard headers altogether.
Balderdash. They should be equally leery of the % operator.
Somehow you started talking like I am saying "I don't want to
use standard headers in my program". Nope.
Your argument (perhaps I have misunderstood it) was that
someone might prefer to use unsigned long instead of size_t
because he would need to include a Standard header to obtain
a size_t definition, and the implementation's headers might
be broken. That's what I think you said; that's what I reject.
>Do you provide a mian() function just in case the implementation has a spelling error?
Ever heard of WinMain() thing? No, I don't provide mian() function.
I also don't eat spoons, and I don't fly.
Yes, I've heard of the WinMain() thing. It's perfectly legal,
but only for free-standing (not hosted) environments. In those
systems, the entire Standard library is optional and you cannot
even rely on the existence of exit(). Those systems do not meet
the requirements the Standard places on hosted systems, and if
they claim to conform to the Standard for hosted systems they
claim incorrectly.
> As for standard headers providing non-Standard definitions: First, there are identifiers that are reserved for future use, meaning that the standard headers are free to define them if they so choose. You are not allowed to use `isosceles' as an identifier with external linkage, and if you do use it you are at fault and not the headers.
Good or bad, but:
NAME
strdup, strndup, strdupa, strndupa - duplicate a string
SYNOPSIS
#define _GNU_SOURCE
#include <string.h>
char *strndup(const char *s, size_t n);
It's not (other) library developers business how user is going
to use strndup, it's personal matter between user and his C
library.
Um, er, haven't you simply illustrated what I wrote? "There
are identifiers that are reserved for future use, meaning that
the standard headers are free to define them." The four strxxx()
identifiers you show are in that class: The implementation is at
liberty to provide them, and if you use `strdup' or `streptomycin'
as an identifier, the clash is your fault, not the implementation's.
"Personal matters" have nothing to do with it: You either tread on
the reserved name space and risk the consequences, or you keep your
distance and remain safe.
The situation is a little tenser if you decide to call upon
strdup() -- or stromboli() -- in your program. The implementation
is permitted to define these identifiers, but is not obliged to do
so and is not obliged to give them any specific meaning. Perhaps
strdup() duplicates a string, but as far as the Standard is concerned
it might just as well cause chocolate pudding to ooze from your
keyboard. *That* might be a "personal matter" between the user and
the C implementation, in the same way that simply assuming a 27-bit
int is a "personal matter."
>Second, if you define reserved identifiers like _GNU_SOURCE you invoke undefined behavior. You may *want* the undefined behavior,
See above, SYNOPSIS section.
As I said, you may want the undefined behavior. That's
one of those "personal matters" you refer to, but not a problem
for C. You're out in the unexplored and exciting territory --
not necessarily a bad place to be, but not a country where the
laws are universally obeyed. Or even understood. If you want
to deal with Roy Bean, "The Hangin' Judge," "The Law West of
the Pecos," that's your lookout. It has its rewards, but also
its dangers.
--
Eric Sosman es*****@acm-dot-org.invalid
Eric Sosman wrote:
Yevgen Muntyan wrote:
>Eric Sosman wrote:
>>Yevgen Muntyan wrote: This Win64 thing is funny, because no other 'popular' system has small long type. Good or bad, but lot of useful software is written under many assumptions like 8-bit bytes, ASCII, long >= size_t. Simply ignoring it won't always work since you might actually need that software (you know, libraries which have useful stuff).
Do you have a specific library in mind, or are you "just supposing?" If the latter, drop it until the situation actually arises. If the former, please tell us about it so we'll be warned not to use that organization's products.
I do have a specific library in mind, indeed. It's not written by me or my friends or relatives. It's a widely used and indeed useful library.
... which you have not named, to warn us away from it.
That's right. Somehow I don't believe you. And somehow I don't want
bring names in this context. Those guys are not hostile, unlike you.
>> Proposition: There is *no* reason to use unsigned long instead of size_t. None. Nada. Zero. Zip. Nulla.
I know none, this is true. You seem to know none. You sure there *isn't* one?
I offered the remark as a "proposition," thus inviting
a counter-example. Got one?
Nope, as I said. Still can't make a conclusion there isn't one.
I don't know way too many things to claim something doesn't exist
because I've never seen it.
>>Every module that performs I/O includes <stdio.hand has size_t defined;
Unless this module use third-party I/O routines, or uses things like open/write. I.e. no, not every.
Yes, "every"
Good you used "quotes" here.
-- unless you've decided to stray outside the
bounds of Standard C. There are good reasons for such strayings,
but you can hardly blame the consequences on the Standard headers.
If the headers in particular implementation are broken, then
they are broken. I don't blame the Standard for that. Not sure
if I blame "Standard headers". And not sure how it is relevant
to whether I use or do not use POSIX read and write.
>Anyway, these three examples are examples of why *user* would use the standard headers. The library itself may not need them. Now, it may be important for the user how he uses the standard headers: what he #define's or in what order he uses the headers, or whatever. Library has no business in that.
Again, I'd be interested to learn the name of this perverse
library you keep alluding to.
Proposition: A library that deals in object sizes but uses
unsigned long instead of size_t to describe them is perverse.
Counter-example?
I know one. If a library has a bug, you call it perverse? I know
*lots*.
>Now, if it's true that one single standard header ever caused problems, then library developers have really good reason to avoid standard headers altogether.
Balderdash. They should be equally leery of the % operator.
I'd think the developers carefully use % operator if it's broken
on some target platform. Is it broken somewhere, did it cause
problems for someone? You seem to imply it.
>Somehow you started talking like I am saying "I don't want to use standard headers in my program". Nope.
Your argument (perhaps I have misunderstood it) was that
someone might prefer to use unsigned long instead of size_t
because he would need to include a Standard header to obtain
a size_t definition, and the implementation's headers might
be broken. That's what I think you said; that's what I reject.
Well, I can't provide any examples of broken standard headers,
I have access only to two systems here, and I am not aware
of some famous example. Does it mean there isn't one? No.
Is there one? I have no idea. Do *I* avoid using standard
headers? *No*. Read the paragraph you replied to?
>>Do you provide a mian() function just in case the implementation has a spelling error?
Ever heard of WinMain() thing? No, I don't provide mian() function. I also don't eat spoons, and I don't fly.
Yes, I've heard of the WinMain() thing. It's perfectly legal,
but only for free-standing (not hosted) environments. In those
systems, the entire Standard library is optional and you cannot
even rely on the existence of exit(). Those systems do not meet
the requirements the Standard places on hosted systems, and if
they claim to conform to the Standard for hosted systems they
claim incorrectly.
I'm glad you provided this useful information, even though it's
irrelevant. But since we're on it, implementation may provide
a separate translation unit which contains definition of main(),
which in turn calls my WinMain. I can ask implementation to do it
for me, and it'd be perfectly legal. I have no idea how exactly
it's done in MS implementation, do you? Come on, let's talk about
what's legal and what's not, exactly on point.
>> As for standard headers providing non-Standard definitions: First, there are identifiers that are reserved for future use, meaning that the standard headers are free to define them if they so choose. You are not allowed to use `isosceles' as an identifier with external linkage, and if you do use it you are at fault and not the headers.
Good or bad, but:
NAME strdup, strndup, strdupa, strndupa - duplicate a string SYNOPSIS #define _GNU_SOURCE #include <string.h>
char *strndup(const char *s, size_t n);
It's not (other) library developers business how user is going to use strndup, it's personal matter between user and his C library.
Um, er, haven't you simply illustrated what I wrote? "There
are identifiers that are reserved for future use, meaning that
the standard headers are free to define them." The four strxxx()
identifiers you show are in that class: The implementation is at
liberty to provide them, and if you use `strdup' or `streptomycin'
as an identifier, the clash is your fault, not the implementation's.
"Personal matters" have nothing to do with it: You either tread on
the reserved name space and risk the consequences, or you keep your
distance and remain safe.
Sorry, what clash? If I don't define _GNU_SOURCE in some way, I
do *not* get declaration of strndup(). glibc provides strndup()
to me but I have to take special measures to use it.
If some library header has '#include <string.h>' then I can't
#define _GNU_SOURCE after it and get strndup() declaration.
If I do #define _GNU_SOURCE before, and the library includes
some more implementation headers, I could get some other stuff
changed, which I may or may not want. And this is exactly the
business for me, a user, not for library to decide which headers,
in what order, and how I use. (_GNU_SOURCE and strndup is
simply a trivial example, people say there are much worse
situations where header order matters)
But even if I wrote totally illegal code which worked fine, it'd be
stupid if some unrelated library broke it. It would be totally fine as
far as the standard is concerned, of course, UB and all that, so what?
For the record, I am not saying I am writing that evil code,
nor am I advocating writing it. (I know, it can't help, you'll
think I ask standard for something, moreover you will think I
ask you for something, and so on)
....
>>Second, if you define reserved identifiers like _GNU_SOURCE you invoke undefined behavior. You may *want* the undefined behavior,
See above, SYNOPSIS section.
As I said, you may want the undefined behavior.
I may want the well-defined behavior which left undefined by
the standard. If the use of _GNU_SOURCE is documented by
implementation, I may use it. But it's not the point of course.
That's
one of those "personal matters" you refer to, but not a problem
for C.
Who said it's a problem for C. Again, you are saying it like I am
claiming standard owes me something, standard is completely wrong,
and I invoke UB every day twice a day.
No, I am saying that library developers may have an attitude
of "user knows better what he's doing".
You're out in the unexplored and exciting territory --
not necessarily a bad place to be, but not a country where the
laws are universally obeyed. Or even understood. If you want
to deal with Roy Bean, "The Hangin' Judge," "The Law West of
the Pecos," that's your lookout. It has its rewards, but also
its dangers.
Poetry...
Yevgen Muntyan wrote:
Eric Sosman wrote:
>Yevgen Muntyan wrote:
>>Eric Sosman wrote: Yevgen Muntyan wrote: This Win64 thing is funny, because no other 'popular' system has small long type. Good or bad, but lot of useful software is written under many assumptions like 8-bit bytes, ASCII, long >= size_t. Simply ignoring it won't always work since you might actually need that software (you know, libraries which have useful stuff).
Do you have a specific library in mind, or are you "just supposing?" If the latter, drop it until the situation actually arises. If the former, please tell us about it so we'll be warned not to use that organization's products.
I do have a specific library in mind, indeed. It's not written by me or my friends or relatives. It's a widely used and indeed useful library.
... which you have not named, to warn us away from it.
That's right. Somehow I don't believe you. And somehow I don't want
bring names in this context. Those guys are not hostile, unlike you.
I think I have to apologize for overreacting. I should not take insults
so close. Perhaps "incompetent" wasn't an insult, it was meant to be
a statement about one's ability to do certain things in right way,
supposedly, but in my dictionary "competent" is a very complex notion,
which is not equivalent to "never makes mistakes". Perhaps supposed
incompetence of certain programmers wasn't a justification for violating
standards by some company. Oh well.
Really sorry,
Yevgen
Yevgen Muntyan said:
Eric Sosman wrote:
>Yevgen Muntyan wrote:
>>> I do have a specific library in mind, indeed. It's not written by me or my friends or relatives. It's a widely used and indeed useful library.
... which you have not named, to warn us away from it.
That's right. Somehow I don't believe you.
It seems that Mr Muntyan is not content with calling me a liar. Now he
is calling Eric Sosman a liar, too. How many more of us will he call
liars before he is through?
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999 http://www.cpax.org.uk
email: rjh at the above domain, - www.
Richard Heathfield wrote:
Yevgen Muntyan said:
>Eric Sosman wrote:
>>Yevgen Muntyan wrote: I do have a specific library in mind, indeed. It's not written by me or my friends or relatives. It's a widely used and indeed useful library. ... which you have not named, to warn us away from it.
That's right. Somehow I don't believe you.
It seems that Mr Muntyan is not content with calling me a liar. Now he
is calling Eric Sosman a liar, too. How many more of us will he call
liars before he is through?
Um, I said I don't believe he wants me to name the library because he
wants to "be warned not to use that organization's products". Does it
qualify as "calling him a liar"? Perhaps. I apologize in that case.
It was a heated argument, with some rude stuff.
If you are saying someone is wrong, does it mean he's a liar? Must be,
since you're saying he said something wrong, that is lied. Or not?
Dear Mr Heathfield, I do understand that saying in public you're not
telling the truth is a bad offense. But when you're making totally
ridiculous statements to justify your rudeness, I simply can't resist.
Hm, somehow I don't believe you're most offended by me calling you
a liar. For some reasons I think the worst thing is disagreement
with you even after you present all your killer
100%-correct-and-ignore-everything-else arguments. Did I just call you a
liar again?
Sorry about that, I do understand I will be hurt by this more than you.
Yevgen
Yevgen Muntyan <mu****************@tamu.eduwrote:
Richard Bos wrote:
Yevgen Muntyan <mu****************@tamu.eduwrote:
Richard Bos wrote: Yevgen Muntyan <mu****************@tamu.eduwrote:
But how is casting size_t to unsigned long more legitimate than
int process_some_data (char *data, unsigned long len); In this case, you could easily make len a size_t instead.
*If* I can change the code.
If _you_ can't change the code, I would advise not to worry about
whether the ideas expressed in it are legitimate or not; leave that to
the people who did design and do maintain it.
That's good and everything, but doesn't always work on practice
unfortunately. If I happen to use some library which uses long instead
of ssize_t, and if I happen to get a dll of that library, I have a
problem.
(If you use ssize_t at all, you have a problem, because that's not an
ISO type and the idea behind it is broken; the only valid reason to have
it in the first place is covered by ptrdiff_t.)
However, if you use a library and you find you can't trust it, your
options are basically to choose a different library, to roll your own,
or to accept that your supervisor doesn't know what he's talking about
and drink the flavorade. Discussing with yourself whether there's a
theoretical possibility of brokenness when you already know that you
will not be able to stop the breakage is reason to file a defect report
with your managers, not reason to fret about it.
By the way, it seems that some people avoid #includ'ing headers like
stddef.h in library headers due to bugs in C implementations
or for some other obscure reasons. I'd think it adds to this
issue: you can use long for free, it's builtin, but to get
size_t you need an extra header.
Given that size_t is also #defined in <stdio.h>, <stdlib.hand
<string.h>, probably the three most #included headers, without which I
can hardly imagine a useful ISO C program of any reasonable size, as
well as in <time.hand <wchar.h>, IMO people who do this should do a
reality check.
Perhaps. Or maybe it's because many vendors put lot of non-standard
stuff into standard headers. Say, if you #include <string.hand
do not #define _GNU_SOURCE with glibc, then you don't get strndup()
declaration.
So? What does that have to do with the price of fish?
You need functions from <string.h>, you #include <string.h>, and you get
size_t for free. Ditto with <stdio.h>, and all the others. If you choose
not to #include a header you should #include because you just _might_
one day have to deal with Ganuck, the difference between unsigned long
and size_t is the least of your problems; getting a grip on your
priorities is much more important.
Richard
Yevgen Muntyan <mu****************@tamu.eduwrote:
Eric Sosman wrote:
Yevgen Muntyan wrote:
Richard Bos wrote: If _you_ can't change the code, I would advise not to worry about whether the ideas expressed in it are legitimate or not; leave that to the people who did design and do maintain it.
That's good and everything, but doesn't always work on practice
unfortunately. If I happen to use some library which uses long instead
of ssize_t, and if I happen to get a dll of that library, I have a
problem.
Yes, indeed. Your problem is that you are using a library
written by somebody who didn't understand C, or who chose to be
deliberately perverse in the way he used it. When the library
writer is hostile or incompetent, you certainly have a problem.
Forgot to mention another evil thing the library does: it uses void*
for function pointers. I wonder if it's caused by hostility or
incompetence.
_The_ library. You obviously have a particular library in mind. Care to
put your money where your mouth is, and name it?
(My first guess would be something coming from M$ itself; in which case
a. The size_t/unsigned long difference is irrelevant because it comes
from the same vendor anyway, and
b. Both. Obviously.)
Richard
Yevgen Muntyan wrote: [... a lot ...]
Eric Sosman wrote: [... too much ...]
Perhaps it's time to review the bidding. This thread
began with your technical question about the implications of
a quiet change in the C99 Standard. I and others explained
how the existence of a size_t wider than unsigned long could
change a program's behavior. You wondered whether this meant
that Win64 was broken, and the consensus seemed to be that it
is. I went on to say that the breakage was unlikely to be
serious, and explained why I thought so. Among my reasons:
nobody would deliberately store size_t values in anything other
than a size_t -- like an unsigned long -- unless there were an
excellent reason to believe the values being stored would be
sufficiently small.
And that's when things got weird, or at least when they
started to elude my understanding. You mentioned a nameless
but useful library that stores sizes in unsigned long, and the
library's existence somehow made me a villain. You are worried
that the library's ill-advised choice of data type might make it
vulnerable to breakage when running on broken Win64, and this
worry somehow makes you angry at me.
I do not understand how the interaction of choices I did not
make and was not responsible for justifies blaming me for the
potential breakage. It's beyond my comprehension, and I give up.
--
Eric Sosman es*****@acm-dot-org.invalid
Yevgen Muntyan wrote, On 16/03/07 06:22:
Richard Heathfield wrote:
>Yevgen Muntyan said:
>>Eric Sosman wrote: Yevgen Muntyan wrote: I do have a specific library in mind, indeed. It's not written by me or my friends or relatives. It's a widely used and indeed useful library. ... which you have not named, to warn us away from it. That's right. Somehow I don't believe you.
It seems that Mr Muntyan is not content with calling me a liar. Now he is calling Eric Sosman a liar, too. How many more of us will he call liars before he is through?
Um, I said I don't believe he wants me to name the library because he
wants to "be warned not to use that organization's products". Does it
qualify as "calling him a liar"? Perhaps. I apologize in that case.
It was a heated argument, with some rude stuff.
If you are saying someone is wrong, does it mean he's a liar? Must be,
since you're saying he said something wrong, that is lied. Or not?
Since you have not named the library, the only other part in statement
you could be disagreeing with is the reason why we would want to know
which library it is. Are you saying that Eric might be mistaken about
why he wants to know the name of the library? If not (and that would be
a ridiculous thing for you to claim) then the logical conclusion is you
think he is lying about why he wants to know the name of the library.
Dear Mr Heathfield, I do understand that saying in public you're not
telling the truth is a bad offense. But when you're making totally
ridiculous statements to justify your rudeness, I simply can't resist.
The last few posts in this thread by Richard and Eric do not seem to be
making ridiculous statements to me, only your posts seem to be doing that.
Hm, somehow I don't believe you're most offended by me calling you
a liar. For some reasons I think the worst thing is disagreement
with you even after you present all your killer
100%-correct-and-ignore-everything-else arguments. Did I just call you a
liar again?
Sorry about that, I do understand I will be hurt by this more than you.
Whether Richard and Eric feel offended or hurt does not change whether
it is an offensive thing to say. As far as I can see the biggest impact
of your attitude here will be to make people think less of you.
--
Flash Gordon
Flash Gordon said:
Yevgen Muntyan wrote, On 16/03/07 06:22:
<snip>
>Hm, somehow I don't believe you're most offended by me calling you a liar. For some reasons I think the worst thing is disagreement with you even after you present all your killer 100%-correct-and-ignore-everything-else arguments. Did I just call you a liar again? Sorry about that, I do understand I will be hurt by this more than you.
Whether Richard and Eric feel offended or hurt does not change whether
it is an offensive thing to say.
Right. And for the record, disagreeing with me has never been cause for
offending me. Lots of people here have disagreed with me - you, no
doubt, Flash, for one - and then there's the Thompson Twins (Keith and
Dave Thompson), and Chris Torek, and Martin, and Chris Dollin, and
Steve, and and Brian, and Ben, and Dann, and plenty more besides - and
sometimes I've been incorrect, and they were right to disagree, and
sometimes I've been correct, and they were /still/ right to disagree,
since the ensuing discussions help to sort out the issue in everyone's
minds. And sometimes we've ended up agreeing to differ. But the mere
fact of disagreement is *not* sufficient to cause offence, and nor
should it be.
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999 http://www.cpax.org.uk
email: rjh at the above domain, - www.
Yevgen Muntyan wrote, On 16/03/07 03:57:
Eric Sosman wrote:
>Yevgen Muntyan wrote:
>>Eric Sosman wrote: Yevgen Muntyan wrote: This Win64 thing is funny, because no other 'popular' system has small long type. Good or bad, but lot of useful software is written under many assumptions like 8-bit bytes, ASCII, long >= size_t. Simply ignoring it won't always work since you might actually need that software (you know, libraries which have useful stuff).
Do you have a specific library in mind, or are you "just supposing?" If the latter, drop it until the situation actually arises. If the former, please tell us about it so we'll be warned not to use that organization's products.
I do have a specific library in mind, indeed. It's not written by me or my friends or relatives. It's a widely used and indeed useful library.
... which you have not named, to warn us away from it.
That's right. Somehow I don't believe you. And somehow I don't want
bring names in this context. Those guys are not hostile, unlike you.
If you are not prepared to provide evidence for you claims then do not
expect people to take them seriously.
>>> Proposition: There is *no* reason to use unsigned long instead of size_t. None. Nada. Zero. Zip. Nulla.
I know none, this is true. You seem to know none. You sure there *isn't* one?
I offered the remark as a "proposition," thus inviting a counter-example. Got one?
Nope, as I said. Still can't make a conclusion there isn't one.
I don't know way too many things to claim something doesn't exist
because I've never seen it.
So because others here can't think of a good reason to use long instead
of size_t and you can't prove there is never such a reason, we must all
assume there could be a good reason to not use the mechanisms provided
by the standard to deal with a problem?
I think you have it backwards. If you are claiming there is a reason to
avoid the mechanisms the standard provides to allow portability then it
is up to *you* to prove your point, not up to others to disprove it.
>>>Every module that performs I/O includes <stdio.hand has size_t defined;
Unless this module use third-party I/O routines, or uses things like open/write. I.e. no, not every.
Yes, "every"
Good you used "quotes" here.
Probably for emphasis. I've never had to include a header just to get
size_t when I wanted it because I've somehow always without thinking
included a header (or more than one) that provides it.
>-- unless you've decided to stray outside the bounds of Standard C. There are good reasons for such strayings, but you can hardly blame the consequences on the Standard headers.
If the headers in particular implementation are broken, then
they are broken. I don't blame the Standard for that. Not sure
if I blame "Standard headers". And not sure how it is relevant
to whether I use or do not use POSIX read and write.
Yet you are using broken headers and headers providing extensions (all
your examples being ones the standard allows them to do that will not
break any otherwise correct code) as a reason for not including them.
Broken headers is not a good reason to not use them since if you cannot
rely on the C implementation you cannot rely on it and need to use a
different one instead.
>>Anyway, these three examples are examples of why *user* would use the standard headers. The library itself may not need them. Now, it may be important for the user how he uses the standard headers: what he #define's or in what order he uses the headers, or whatever. Library has no business in that.
Again, I'd be interested to learn the name of this perverse library you keep alluding to.
Proposition: A library that deals in object sizes but uses unsigned long instead of size_t to describe them is perverse. Counter-example?
I know one. If a library has a bug, you call it perverse? I know
*lots*.
Provide ONE specific example where a library has a broken header (give
the name and version of the library) which is bad enough to cause
problems with otherwise correct code.
>>Now, if it's true that one single standard header ever caused problems, then library developers have really good reason to avoid standard headers altogether.
Balderdash. They should be equally leery of the % operator.
I'd think the developers carefully use % operator if it's broken
on some target platform. Is it broken somewhere, did it cause
problems for someone? You seem to imply it.
1+1 is broken on at least one implementation (well, it was something
fundamental like that), should we avoid adding that as a result? No, you
file a bug report on the library (or processor in this case) and tell
your user base not to use it because it is broken. I know, because I
work in a commercial organisation and we *do* tell them that they cannot
use certain things with our software because they are broken.
>>Somehow you started talking like I am saying "I don't want to use standard headers in my program". Nope.
Your argument (perhaps I have misunderstood it) was that someone might prefer to use unsigned long instead of size_t because he would need to include a Standard header to obtain a size_t definition, and the implementation's headers might be broken. That's what I think you said; that's what I reject.
Well, I can't provide any examples of broken standard headers,
I have access only to two systems here, and I am not aware
of some famous example. Does it mean there isn't one? No.
Is there one? I have no idea. Do *I* avoid using standard
headers? *No*. Read the paragraph you replied to?
The contention of everyone else is that there is no implementation worth
bothering with that has headers sufficiently broken to be worth worrying
about. There is a very good reason for this, and such implementation
would be well publicised and boycotted until it was fixed, so a short
time after it is released it will be of historic interest only because
the free bugfix will be available.
Again, it is up to *you* to prove your contention that there are reasons
to avoid standard headers due to problems, because the purpose of the
standard is to provide you with the guarantees that you do not need to
worry about such things.
>>>Do you provide a mian() function just in case the implementation has a spelling error?
Ever heard of WinMain() thing? No, I don't provide mian() function. I also don't eat spoons, and I don't fly.
Yes, I've heard of the WinMain() thing. It's perfectly legal, but only for free-standing (not hosted) environments. In those systems, the entire Standard library is optional and you cannot even rely on the existence of exit(). Those systems do not meet the requirements the Standard places on hosted systems, and if they claim to conform to the Standard for hosted systems they claim incorrectly.
I'm glad you provided this useful information, even though it's
irrelevant.
It is entirely relevant since it shows that your suggesting WinMain as a
counter-example was *not* a valid counter-example.
But since we're on it, implementation may provide
a separate translation unit which contains definition of main(),
which in turn calls my WinMain.
It can't if it is a hosted implementation. It is actually well known
that when compiling applications for the Window GUI using MS VC++ you
are using a freestanding implementation.
I can ask implementation to do it
for me, and it'd be perfectly legal. I have no idea how exactly
it's done in MS implementation, do you? Come on, let's talk about
what's legal and what's not, exactly on point.
WinMain is legal because it is a FREESTANDING implementation, all
appearances to the contrary. When you invoke MS VC++ as a hosted
implementation *you* have to provide main, so it is not a counter example.
>>> As for standard headers providing non-Standard definitions: First, there are identifiers that are reserved for future use, meaning that the standard headers are free to define them if they so choose. You are not allowed to use `isosceles' as an identifier with external linkage, and if you do use it you are at fault and not the headers.
Good or bad, but:
NAME strdup, strndup, strdupa, strndupa - duplicate a string SYNOPSIS #define _GNU_SOURCE #include <string.h>
char *strndup(const char *s, size_t n);
It's not (other) library developers business how user is going to use strndup, it's personal matter between user and his C library.
Um, er, haven't you simply illustrated what I wrote? "There are identifiers that are reserved for future use, meaning that the standard headers are free to define them." The four strxxx() identifiers you show are in that class: The implementation is at liberty to provide them, and if you use `strdup' or `streptomycin' as an identifier, the clash is your fault, not the implementation's. "Personal matters" have nothing to do with it: You either tread on the reserved name space and risk the consequences, or you keep your distance and remain safe.
Sorry, what clash?
That is the point. If you (and this mythical library that has to avoid
use of standard headers) do not invade the implementation namespace then
there is no clash, so the headers declaring strdup is not a problem. If
you or the mythical third party library do then it is *your* code, or
that mythical library, that is broken *not* the standard header.
If I don't define _GNU_SOURCE in some way, I
do *not* get declaration of strndup(). glibc provides strndup()
to me but I have to take special measures to use it.
If some library header has '#include <string.h>' then I can't
#define _GNU_SOURCE after it and get strndup() declaration.
If I do #define _GNU_SOURCE before, and the library includes
some more implementation headers, I could get some other stuff
changed, which I may or may not want.
Give exactly ONE example of something it will break where you or your
mythical library is not already broken due to invading the
implementations namespace.
And this is exactly the
business for me, a user, not for library to decide which headers,
in what order, and how I use. (_GNU_SOURCE and strndup is
simply a trivial example, people say there are much worse
situations where header order matters)
People say the earth is flat, that does not make it true. People also
say the earth is not flat, and them saying that does not make it true
either.
But even if I wrote totally illegal code which worked fine, it'd be
stupid if some unrelated library broke it. It would be totally fine as
far as the standard is concerned, of course, UB and all that, so what?
For the record, I am not saying I am writing that evil code,
nor am I advocating writing it. (I know, it can't help, you'll
think I ask standard for something, moreover you will think I
ask you for something, and so on)
You are advocating that there are good reasons to write stupidly broken
code when writing a library, everyone else is saying you are wrong. If
you want to convince anyone that you are correct, or even that you have
a valid if mistaken point of view, then *you* have to provide some
concrete example, not hand waving and saying you know this library that
does it and you are sure that it is because of broken headers and they
have a good reason.
>
...
>>>Second, if you define reserved identifiers like _GNU_SOURCE you invoke undefined behavior. You may *want* the undefined behavior,
See above, SYNOPSIS section.
As I said, you may want the undefined behavior.
I may want the well-defined behavior which left undefined by
the standard. If the use of _GNU_SOURCE is documented by
implementation, I may use it. But it's not the point of course.
>That's one of those "personal matters" you refer to, but not a problem for C.
Who said it's a problem for C. Again, you are saying it like I am
claiming standard owes me something, standard is completely wrong,
and I invoke UB every day twice a day.
No, I am saying that library developers may have an attitude
of "user knows better what he's doing".
You are saying that the writer of a third party library has to do
something everyone else considers stupid to prevent it being broken when
you do something legal on a specific implementation. I say this is
complete rubbish and the writer of the third party library should use
the standard mechanisms provided. Either proved *real* *verifiable*
evidence of your claim that there are good reasons or accept that the
writers of that library have done the wrong thing.
--
Flash Gordon
Flash Gordon wrote:
Yevgen Muntyan wrote, On 16/03/07 06:22:
>Richard Heathfield wrote:
>>Yevgen Muntyan said:
Eric Sosman wrote: Yevgen Muntyan wrote: >I do have a specific library in mind, indeed. It's not written by me >or my friends or relatives. It's a widely used and indeed useful >library. ... which you have not named, to warn us away from it. That's right. Somehow I don't believe you.
It seems that Mr Muntyan is not content with calling me a liar. Now he is calling Eric Sosman a liar, too. How many more of us will he call liars before he is through?
Um, I said I don't believe he wants me to name the library because he wants to "be warned not to use that organization's products". Does it qualify as "calling him a liar"? Perhaps. I apologize in that case. It was a heated argument, with some rude stuff. If you are saying someone is wrong, does it mean he's a liar? Must be, since you're saying he said something wrong, that is lied. Or not?
Since you have not named the library, the only other part in statement
you could be disagreeing with is the reason why we would want to know
which library it is. Are you saying that Eric might be mistaken about
why he wants to know the name of the library? If not (and that would be
a ridiculous thing for you to claim) then the logical conclusion is you
think he is lying about why he wants to know the name of the library.
I should be careful then, if someone jumps to calling people he doesn't
know incompetent, I must stay superpolite in order not to get in danger
of calling him a liar when he says fancy-shmancy "so we are warned...".
>Dear Mr Heathfield, I do understand that saying in public you're not telling the truth is a bad offense. But when you're making totally ridiculous statements to justify your rudeness, I simply can't resist.
The last few posts in this thread by Richard and Eric do not seem to be
making ridiculous statements to me, only your posts seem to be doing that.
Um, Mr Richard didn't quote me calling him a liar, did he? It wasn't
about last few posts in this thread. Or do you mean Mr Heathfield is
liar? Then, I didn't mean Eric words. I said "Mr Heathfield". What I
said to Mr Richard has nothing to do with what I said to Eric Sosman.
>Hm, somehow I don't believe you're most offended by me calling you a liar. For some reasons I think the worst thing is disagreement with you even after you present all your killer 100%-correct-and-ignore-everything-else arguments. Did I just call you a liar again? Sorry about that, I do understand I will be hurt by this more than you.
Whether Richard and Eric feel offended or hurt does not change whether
it is an offensive thing to say.
So it's fine for Eric to insult other people by calling them
incompetent, but it was so bad from me to say an offensive thing?
And again, what I said to Richard is different. Note, I didn't
invite him nor I mentioned him here. He came whining I called
him a liar elsewhere. "Oh what are we gonna do!"
As far as I can see the biggest impact
of your attitude here will be to make people think less of you.
Perhaps. I do understand that you have to earn right to be an asshole,
like Mr Heathfield has.
Yevgen
Eric Sosman wrote:
Yevgen Muntyan wrote: [... a lot ...]
>Eric Sosman wrote: [... too much ...]
Perhaps it's time to review the bidding. This thread
began with your technical question about the implications of
a quiet change in the C99 Standard. I and others explained
how the existence of a size_t wider than unsigned long could
change a program's behavior. You wondered whether this meant
that Win64 was broken, and the consensus seemed to be that it
is. I went on to say that the breakage was unlikely to be
serious, and explained why I thought so. Among my reasons:
nobody would deliberately store size_t values in anything other
than a size_t -- like an unsigned long -- unless there were an
excellent reason to believe the values being stored would be
sufficiently small.
And that's when things got weird, or at least when they
started to elude my understanding. You mentioned a nameless
but useful library that stores sizes in unsigned long, and the
library's existence somehow made me a villain. You are worried
that the library's ill-advised choice of data type might make it
vulnerable to breakage when running on broken Win64, and this
worry somehow makes you angry at me.
I do not understand how the interaction of choices I did not
make and was not responsible for justifies blaming me for the
potential breakage. It's beyond my comprehension, and I give up.
Well, it wasn't quite like that. Let me quote:
>Given that size_t is also #defined in <stdio.h>, <stdlib.hand <string.h>, probably the three most #included headers, without which I can hardly imagine a useful ISO C program of any reasonable size, as well as in <time.hand <wchar.h>, IMO people who do this should do a reality check.
Perhaps. Or maybe it's because many vendors put lot of non-standard
stuff into standard headers. Say, if you #include <string.hand
do not #define _GNU_SOURCE with glibc, then you don't get strndup()
declaration. But then library (not the C library) may not mandate
what you get and what you don't from the C library. So it would
need to document its headers include <string.h>, <foo.h>, and whatnot.
And then it must maintain that forever. Don't know, playing devil
advocate here.
And then you said in particular
Second, if you define reserved identifiers
like _GNU_SOURCE you invoke undefined behavior. You may *want* the
undefined behavior, but you can't ask the Standard to bless your
perverted desires.
So you talked like I am justifying using _GNU_SOURCE or
I am justifying UB, and moreover I want standard to bless it.
But I said that the library developers may opt to *allow user*
invoke UB (this one in this particular case *is* defined and
documented), or use implementation-specific features and whatnot.
That was one part.
Another part is calling the library developers incompetent. I can
just as well say you are incompetent and prove it (except one
part which doesn't need proving): you are incompetent because
your software has bugs. Or not? I wouldn't say you're incompetent
because of that.
Oh well, whatever. It's beyond your comprehension that people
may not mean anything but what they're saying. You're reading
between the lines, but not what I put in there. I guess it's
the reason for you not understanding the lines either.
Yevgen
Flash Gordon wrote:
Yevgen Muntyan wrote, On 16/03/07 03:57:
>Eric Sosman wrote:
>>Yevgen Muntyan wrote: Eric Sosman wrote: Yevgen Muntyan wrote: >This Win64 thing is funny, because no other 'popular' system >has small long type. Good or bad, but lot of useful software is >written >under many assumptions like 8-bit bytes, ASCII, long >= size_t. >Simply >ignoring it won't always work since you might actually need that >software (you know, libraries which have useful stuff). > Do you have a specific library in mind, or are you "just supposing?" If the latter, drop it until the situation actually arises. If the former, please tell us about it so we'll be warned not to use that organization's products.
I do have a specific library in mind, indeed. It's not written by me or my friends or relatives. It's a widely used and indeed useful library.
... which you have not named, to warn us away from it.
That's right. Somehow I don't believe you. And somehow I don't want bring names in this context. Those guys are not hostile, unlike you.
If you are not prepared to provide evidence for you claims then do not
expect people to take them seriously.
For what claim exactly? That there is such a library? Are you calling me
a liar? And no, I don't want to bring names in this context, regardless
of how people take my claims. Especially if they don't take them
seriously regardless. You know, if I am accused of asking standard to
bless using UB (read the thread if you like), then I can be said to fly
to Mars and whatnot. And then what?
>>>> Proposition: There is *no* reason to use unsigned long instead of size_t. None. Nada. Zero. Zip. Nulla.
I know none, this is true. You seem to know none. You sure there *isn't* one?
I offered the remark as a "proposition," thus inviting a counter-example. Got one?
Nope, as I said. Still can't make a conclusion there isn't one. I don't know way too many things to claim something doesn't exist because I've never seen it.
So because others here can't think of a good reason to use long instead
of size_t and you can't prove there is never such a reason, we must all
assume there could be a good reason to not use the mechanisms provided
by the standard to deal with a problem?
I think you have it not even backwards. I said that some people *may*
have good reasons. If you say that fact of you, Eric, me, and two
other people not knowing such a good reason implies non-existence of
such a reason, then I will disagree.
But in fact, I was trying to make up reasons "why people would not
want to have standard headers included in their own headers which
do not use features from standard headers". It's in fact even not
very relevant to the "evil library", because it has dedicated type
to serve same purpose as size_t, and long instead of size_t was
in fact a mistake, and then there is backwards compatibility, api
stability and all that.
But you folks decided I am defending this particular thing, and
to justify that I accuse standard of causing all my problems. It
surely is easier to argue with.
I think you have it backwards. If you are claiming there is a reason to
avoid the mechanisms the standard provides to allow portability then it
is up to *you* to prove your point, not up to others to disprove it.
I am claiming this: my (and yours, and Eric's, and all the regulars
here) lack of knowledge about one particular obscure system does
*not* imply I (you, Eric, etc.) *know* something about it. If
I write code, I don't worry about those obscure systems. But I
admit a possibility of someone who does worry about obscure system
I never heard about. I do *not* claim existence of that system.
Not sure what I need to prove here.
>>>>Every module that performs I/O includes <stdio.hand has size_t defined;
Unless this module use third-party I/O routines, or uses things like open/write. I.e. no, not every.
Yes, "every"
Good you used "quotes" here.
Probably for emphasis.
I doubt it. Read the sentence. "Every module that performs I/O includes
<stdio.h>". It is not true. "Every" was put in quotes to make it "true".
I've never had to include a header just to get
size_t when I wanted it because I've somehow always without thinking
included a header (or more than one) that provides it.
Same thing. I rarely use size_t in fact. I did though have modules
which perform I/O and do not use stdio.h.
>>-- unless you've decided to stray outside the bounds of Standard C. There are good reasons for such strayings, but you can hardly blame the consequences on the Standard headers.
If the headers in particular implementation are broken, then they are broken. I don't blame the Standard for that. Not sure if I blame "Standard headers". And not sure how it is relevant to whether I use or do not use POSIX read and write.
Yet you are using broken headers and headers providing extensions (all
your examples being ones the standard allows them to do that will not
break any otherwise correct code) as a reason for not including them.
Broken headers is not a good reason to not use them since if you cannot
rely on the C implementation you cannot rely on it and need to use a
different one instead.
This is a very wrong thing. There may be localized bugs which have
to be worked around. It's a source distribution world, you can't
say "Fnu compiler is broken, we shall not use it", you have to
work it around if it's not too hard. Seen gnulib?
>>>Anyway, these three examples are examples of why *user* would use the standard headers. The library itself may not need them. Now, it may be important for the user how he uses the standard headers: what he #define's or in what order he uses the headers, or whatever. Library has no business in that.
Again, I'd be interested to learn the name of this perverse library you keep alluding to.
Proposition: A library that deals in object sizes but uses unsigned long instead of size_t to describe them is perverse. Counter-example?
I know one. If a library has a bug, you call it perverse? I know *lots*.
Provide ONE specific example where a library has a broken header (give
the name and version of the library) which is bad enough to cause
problems with otherwise correct code.
So you can all jump around and yell "those guys are incompetent morons
how cool we are"?
>>>Now, if it's true that one single standard header ever caused problems, then library developers have really good reason to avoid standard headers altogether.
Balderdash. They should be equally leery of the % operator.
I'd think the developers carefully use % operator if it's broken on some target platform. Is it broken somewhere, did it cause problems for someone? You seem to imply it.
1+1 is broken on at least one implementation (well, it was something
fundamental like that), should we avoid adding that as a result?
If your code is going to work on that implementation, yes.
No, you
file a bug report on the library (or processor in this case) and tell
your user base not to use it because it is broken.
Totally funny.
I know, because I
work in a commercial organisation and we *do* tell them that they cannot
use certain things with our software because they are broken.
Well, it's different world. You can't say "don't use glibc" or
"don't use FreeBSD C library" or "don't use operating system
you're using".
>>>Somehow you started talking like I am saying "I don't want to use standard headers in my program". Nope.
Your argument (perhaps I have misunderstood it) was that someone might prefer to use unsigned long instead of size_t because he would need to include a Standard header to obtain a size_t definition, and the implementation's headers might be broken. That's what I think you said; that's what I reject.
Well, I can't provide any examples of broken standard headers, I have access only to two systems here, and I am not aware of some famous example. Does it mean there isn't one? No. Is there one? I have no idea. Do *I* avoid using standard headers? *No*. Read the paragraph you replied to?
The contention of everyone else
"everyone else" is three people including you? Perhaps you are right,
I don't know. But I don't know enough to make such a conclusion.
is that there is no implementation worth
bothering with that has headers sufficiently broken to be worth worrying
about. There is a very good reason for this, and such implementation
would be well publicised and boycotted until it was fixed,
You are kidding, right? How about MS?
Oh, of course, you stopped generalizing and now you are talking about
size_t. Yes, I can't believe there is an implementation which doesn't
have size_t correctly defined in stddef.h. I somehow talked about
the general thing of people not wanting to use standard headers.
You can read it upthread.
so a short
time after it is released it will be of historic interest only because
the free bugfix will be available.
Again, it is up to *you* to prove your contention that there are reasons
to avoid standard headers due to problems,
I can't prove it, and I am not going to, since I simply don't know
if it's true. But I don't claim it's false just because I don't know
any example.
because the purpose of the
standard is to provide you with the guarantees that you do not need to
worry about such things.
>>>>Do you provide a mian() function just in case the implementation has a spelling error?
Ever heard of WinMain() thing? No, I don't provide mian() function. I also don't eat spoons, and I don't fly.
Yes, I've heard of the WinMain() thing. It's perfectly legal, but only for free-standing (not hosted) environments. In those systems, the entire Standard library is optional and you cannot even rely on the existence of exit(). Those systems do not meet the requirements the Standard places on hosted systems, and if they claim to conform to the Standard for hosted systems they claim incorrectly.
I'm glad you provided this useful information, even though it's irrelevant.
It is entirely relevant since it shows that your suggesting WinMain as a
counter-example was *not* a valid counter-example.
You mean "mian" was relevant to anything?
But since we're on it, implementation may provide a separate translation unit which contains definition of main(), which in turn calls my WinMain.
It can't if it is a hosted implementation.
Yes it can, why can't it? Execution starts in main(), everything
is fine.
It is actually well known
that when compiling applications for the Window GUI using MS VC++ you
are using a freestanding implementation.
With MS VC++ maybe. I can use other compilers which *might* use
hidden main(). Can you *prove* (you love proofs don't you) my
favorite compiler doesn't do what I say? (I have no idea what
it does really)
I can ask implementation to do it for me, and it'd be perfectly legal. I have no idea how exactly it's done in MS implementation, do you? Come on, let's talk about what's legal and what's not, exactly on point.
WinMain is legal because it is a FREESTANDING implementation, all
appearances to the contrary. When you invoke MS VC++ as a hosted
implementation *you* have to provide main, so it is not a counter example.
Again, I don't know how to use MS VC++.
>>>> As for standard headers providing non-Standard definitions: First, there are identifiers that are reserved for future use, meaning that the standard headers are free to define them if they so choose. You are not allowed to use `isosceles' as an identifier with external linkage, and if you do use it you are at fault and not the headers.
Good or bad, but:
NAME strdup, strndup, strdupa, strndupa - duplicate a string SYNOPSIS #define _GNU_SOURCE #include <string.h>
char *strndup(const char *s, size_t n);
It's not (other) library developers business how user is going to use strndup, it's personal matter between user and his C library.
Um, er, haven't you simply illustrated what I wrote? "There are identifiers that are reserved for future use, meaning that the standard headers are free to define them." The four strxxx() identifiers you show are in that class: The implementation is at liberty to provide them, and if you use `strdup' or `streptomycin' as an identifier, the clash is your fault, not the implementation's. "Personal matters" have nothing to do with it: You either tread on the reserved name space and risk the consequences, or you keep your distance and remain safe.
Sorry, what clash?
That is the point. If you (and this mythical library that has to avoid
use of standard headers) do not invade the implementation namespace then
there is no clash, so the headers declaring strdup is not a problem. If
you or the mythical third party library do then it is *your* code, or
that mythical library, that is broken *not* the standard header.
You didn't get it either.
#include <foo-thelib.h>
#define _GNU_SOURCE
#include <string.h>
void bar (void)
{
strndup ("33", 1);
}
If foo.h includes string.h, then strndup() won't be declared.
Whose problem is this? User's. Why does it happen? Because
user is stupid, he should #define _GNU_SOURCE at the very
beginning. Is the library right? No.
And this is exactly the business for me, a user, not for library to decide which headers, in what order, and how I use. (_GNU_SOURCE and strndup is simply a trivial example, people say there are much worse situations where header order matters)
People say the earth is flat, that does not make it true. People also
say the earth is not flat, and them saying that does not make it true
either.
It's not about the truth. It's about you not having right to tell others
people earth is round (it's not, you know).
>But even if I wrote totally illegal code which worked fine, it'd be stupid if some unrelated library broke it. It would be totally fine as far as the standard is concerned, of course, UB and all that, so what?
For the record, I am not saying I am writing that evil code, nor am I advocating writing it. (I know, it can't help, you'll think I ask standard for something, moreover you will think I ask you for something, and so on)
You are advocating that there are good reasons to write stupidly broken
code when writing a library,
Am I?
everyone else is saying you are wrong. If
you want to convince anyone that you are correct, or even that you have
a valid if mistaken point of view, then *you* have to provide some
concrete example, not hand waving and saying you know this library that
does it and you are sure that it is because of broken headers and they
have a good reason.
>> ...
>>>>Second, if you define reserved identifiers like _GNU_SOURCE you invoke undefined behavior. You may *want* the undefined behavior,
See above, SYNOPSIS section.
As I said, you may want the undefined behavior.
I may want the well-defined behavior which left undefined by the standard. If the use of _GNU_SOURCE is documented by implementation, I may use it. But it's not the point of course.
>>That's one of those "personal matters" you refer to, but not a problem for C.
Who said it's a problem for C. Again, you are saying it like I am claiming standard owes me something, standard is completely wrong, and I invoke UB every day twice a day. No, I am saying that library developers may have an attitude of "user knows better what he's doing".
You are saying that the writer of a third party library has to do
something everyone else considers stupid to prevent it being broken when
you do something legal on a specific implementation. I say this is
complete rubbish and the writer of the third party library should use
the standard mechanisms provided. Either proved *real* *verifiable*
evidence of your claim that there are good reasons or accept that the
writers of that library have done the wrong thing.
Still, I can't do either. I can't accept something has done a wrong
thing simply because I don't know the reason he did it. If you can
it's your right. Of course, your opinion is backed up by opinions
of other three people in this newsgroup, of yeah, collective wisdom.
Just tell, why does gnulib exist, why does it have so many wrappers
for so many *standard* things? Because people working on it are
stupid?
Yevgen
Richard Bos wrote:
Yevgen Muntyan <mu****************@tamu.eduwrote:
>Richard Bos wrote:
>>Yevgen Muntyan <mu****************@tamu.eduwrote:
Richard Bos wrote: Yevgen Muntyan <mu****************@tamu.eduwrote: > >But how is casting size_t to unsigned long more legitimate than >> >int process_some_data (char *data, unsigned long len); In this case, you could easily make len a size_t instead. *If* I can change the code. If _you_ can't change the code, I would advise not to worry about whether the ideas expressed in it are legitimate or not; leave that to the people who did design and do maintain it.
That's good and everything, but doesn't always work on practice unfortunately. If I happen to use some library which uses long instead of ssize_t, and if I happen to get a dll of that library, I have a problem.
(If you use ssize_t at all, you have a problem, because that's not an
ISO type and the idea behind it is broken; the only valid reason to have
it in the first place is covered by ptrdiff_t.)
However, if you use a library and you find you can't trust it, your
options are basically to choose a different library, to roll your own,
or to accept that your supervisor doesn't know what he's talking about
and drink the flavorade.
Oh well, it's glib, and you're talking nonsense. *If* I don't trust
it lalala. I do trust it.
Discussing with yourself whether there's a
theoretical possibility of brokenness when you already know that you
will not be able to stop the breakage is reason to file a defect report
with your managers, not reason to fret about it.
>>>By the way, it seems that some people avoid #includ'ing headers like stddef.h in library headers due to bugs in C implementations or for some other obscure reasons. I'd think it adds to this issue: you can use long for free, it's builtin, but to get size_t you need an extra header. Given that size_t is also #defined in <stdio.h>, <stdlib.hand <string.h>, probably the three most #included headers, without which I can hardly imagine a useful ISO C program of any reasonable size, as well as in <time.hand <wchar.h>, IMO people who do this should do a reality check.
Perhaps. Or maybe it's because many vendors put lot of non-standard stuff into standard headers. Say, if you #include <string.hand do not #define _GNU_SOURCE with glibc, then you don't get strndup() declaration.
So? What does that have to do with the price of fish?
#include <glib.h>
#define _GNU_SOURCE
#include <string.h>
#undef _GNU_SOURCE
#include <stdlib.h>
void foo (void)
{
strndup ("d", 1);
}
This code is broken if glib.h #include's string.h. If you were a glib
developer (which I guess is good you aren't), you could decide it's not
a good thing. If it does need string.h (which it doesn't), it would
need to document it, and *always* include it, forever. I have no idea
what funny target platforms considerations may affect desicions like
this. glib is not a fancy standard-C-only library, and it can't rely
solely on guarantees made by the C standard.
You need functions from <string.h>, you #include <string.h>, and you get
size_t for free. Ditto with <stdio.h>, and all the others. If you choose
not to #include a header you should #include because you just _might_
one day have to deal with Ganuck, the difference between unsigned long
and size_t is the least of your problems; getting a grip on your
priorities is much more important.
The difference between long and size_t has nothing to with this headers
business in fact. Try reading my post where I brought it in.
Yevgen
Yevgen Muntyan wrote:
Eric Sosman wrote:
.... snip ...
>> Libraries that have useful stuff *and* for which no practical alternatives exist *and* were written by incompetents or hostiles.
It's surely the easiest to walk a problem around by calling others
incompetent, especially if it's not your problem.
> Do you have a specific library in mind, or are you "just supposing?" If the latter, drop it until the situation actually arises. If the former, please tell us about it so we'll be warned not to use that organization's products.
I do have a specific library in mind, indeed. It's not written by
me or my friends or relatives. It's a widely used and indeed useful
library.
So why are you hiding its identity, after a specific request for
such?
--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
--
Posted via a free Usenet account from http://www.teranews.com
Yevgen Muntyan wrote, On 16/03/07 15:26:
Flash Gordon wrote:
>Yevgen Muntyan wrote, On 16/03/07 06:22:
>>Richard Heathfield wrote: Yevgen Muntyan said:
Eric Sosman wrote: >Yevgen Muntyan wrote: >>I do have a specific library in mind, indeed. It's not written by me >>or my friends or relatives. It's a widely used and indeed useful >>library. > ... which you have not named, to warn us away from it. That's right. Somehow I don't believe you.
It seems that Mr Muntyan is not content with calling me a liar. Now he is calling Eric Sosman a liar, too. How many more of us will he call liars before he is through?
Um, I said I don't believe he wants me to name the library because he wants to "be warned not to use that organization's products". Does it qualify as "calling him a liar"? Perhaps. I apologize in that case. It was a heated argument, with some rude stuff. If you are saying someone is wrong, does it mean he's a liar? Must be, since you're saying he said something wrong, that is lied. Or not?
Since you have not named the library, the only other part in statement you could be disagreeing with is the reason why we would want to know which library it is. Are you saying that Eric might be mistaken about why he wants to know the name of the library? If not (and that would be a ridiculous thing for you to claim) then the logical conclusion is you think he is lying about why he wants to know the name of the library.
I should be careful then, if someone jumps to calling people he doesn't
know incompetent, I must stay superpolite in order not to get in danger
of calling him a liar when he says fancy-shmancy "so we are warned...".
You should always try to stay polite. So should Richard (all of them),
Eric, myself and everyone else. Not everyone stays polite all the time
and some may not even try, but someone else being impolite does not give
you (or anyone else) license to be impolite. You should be especially
careful of saying things that could be interpreted as implying someone
is lying.
>>Dear Mr Heathfield, I do understand that saying in public you're not telling the truth is a bad offense. But when you're making totally ridiculous statements to justify your rudeness, I simply can't resist.
The last few posts in this thread by Richard and Eric do not seem to be making ridiculous statements to me, only your posts seem to be doing that.
Um, Mr Richard didn't quote me calling him a liar, did he? It wasn't
about last few posts in this thread. Or do you mean Mr Heathfield is
liar? Then, I didn't mean Eric words. I said "Mr Heathfield". What I
said to Mr Richard has nothing to do with what I said to Eric Sosman.
I've never noticed either Richard Heathfield or Eric lying. I've seen
them make mistakes, and I've certainly disagreed with Richard in the
past (I don't keep score, but he has probably been right more often than
me). However the way you have been attacking in this thread I can
certainly see how what you've said can be interpreted as implying they
are lying, in particular what you say above about Eric's comment.
>>Hm, somehow I don't believe you're most offended by me calling you a liar. For some reasons I think the worst thing is disagreement with you even after you present all your killer 100%-correct-and-ignore-everything-else arguments. Did I just call you a liar again? Sorry about that, I do understand I will be hurt by this more than you.
Whether Richard and Eric feel offended or hurt does not change whether it is an offensive thing to say.
So it's fine for Eric to insult other people by calling them
incompetent, but it was so bad from me to say an offensive thing?
The evidence you present suggests that they are incompetent. I suspect
however that what was intended, even if not said, is that if they are
doing what you say for the reasons they give then they are incompetent,
otherwise you are misrepresenting them. Note the conditional. Currently
I would not want to wager which it is, and your failure to let us know
the library in question only makes things worse.
And again, what I said to Richard is different. Note, I didn't
invite him nor I mentioned him here. He came whining I called
him a liar elsewhere. "Oh what are we gonna do!"
Any post here is an invitation for *everyone* to comment. I suggest that
in this case Richard was referring to things you have said either else
where in this thread or in another thread.
>As far as I can see the biggest impact of your attitude here will be to make people think less of you.
Perhaps. I do understand that you have to earn right to be an asshole,
like Mr Heathfield has.
You have to earn respect, and violently disagreeing with very
knowledgeable people without being prepared to provide any significant
backing for your argument is a good way to loose any respect people have
for you and prevent them from respecting you in the future.
Respect earns you a certain latitude. It may not be fair, but it is the
way human interactions work. So yes, you do have to earn the right to be
an asshole if you want to get away with it, which is not to say that I
consider Richard to be an asshole.
--
Flash Gordon
"Yevgen Muntyan" <mu****************@tamu.eduwrote in message
news:osYJh.5718$Bi2.67@trnddc01...
Eric Sosman wrote:
> If size_t is wider than long, the implementation cannot conform to C89. It could, however, conform to C99, with size_t being as wide as long long or as some other wide type. One of the (many) things I don't know about MS Win64 is what standards it claims to conform to.
It claims conformance to C90. It does not conform to C99.
Win64 itself doesn't claim conformance with anything; since it's not a
complete implementation, it couldn't anyways. It's merely an API.
Individual compilers may or may not be compliant; I don't see how
an IL32LLP64 system could be C90-compliant , but it could be
C99-compliant. However, MSVC doesn't even attempt to be C99-
compliant. Since the _vast_ majority of code compiled with it is
blatantly unportable to any other implementation anyways, they can
get away with it. Another implementation for Win64 could be
C99-compliant if the authors wished.
(And for the record, MS wanted to do I32LP64, but they discovered that broke
nearly every program they tried to port, whereas IL32LLP64 allowed nearly
all of them to compile and work unchanged.)
S
--
Stephen Sprunk "Those people who think they know everything
CCIE #3723 are a great annoyance to those of us who do."
K5SSS --Isaac Asimov
--
Posted via a free Usenet account from http://www.teranews.com
In article <kv************@news.flash-gordon.me.uk>,
Flash Gordon <sp**@flash-gordon.me.ukwrote:
I've never had to include a header just to get size_t when I wanted it because I've somehow always without thinking included a header (or more than one) that provides it.
I can make a stronger statement than that:
I've started writing code, decided I wanted to use a size_t, and therefore
added (or made a mental note to add) a "#include <stddef.h>"...
But every time, I've ended up (often as the next thing I do) adding a
call to a standard library function declared in a header that defines
size_t anyways. So I've never had a reason to #include <stddef.h>
by the time I let a compiler see the code.
dave
--
Dave Vandervies dj******@csclub.uwaterloo.ca
>No? Then I should find something else or (how horrible!) have some work done.
WORK??? I think that would be overreacting.
--Peter Pichler and Richard Heathfield in comp.lang.c
Stephen Sprunk wrote:
"Yevgen Muntyan" <mu****************@tamu.eduwrote in message
news:osYJh.5718$Bi2.67@trnddc01...
>Eric Sosman wrote:
>> If size_t is wider than long, the implementation cannot conform to C89. It could, however, conform to C99, with size_t being as wide as long long or as some other wide type. One of the (many) things I don't know about MS Win64 is what standards it claims to conform to.
It claims conformance to C90. It does not conform to C99.
Win64 itself doesn't claim conformance with anything; since it's not a
complete implementation, it couldn't anyways. It's merely an API.
Win64 isn't, "visual C runtime library" or whatever it's called with
their compiler is. The conformance claim is at msdn.com for instance,
you can find it linked from clc wiki.
Flash Gordon wrote:
Yevgen Muntyan wrote, On 16/03/07 15:26:
>Flash Gordon wrote:
>>Yevgen Muntyan wrote, On 16/03/07 06:22:
[snip]
>>>Dear Mr Heathfield, I do understand that saying in public you're not telling the truth is a bad offense. But when you're making totally ridiculous statements to justify your rudeness, I simply can't resist.
The last few posts in this thread by Richard and Eric do not seem to be making ridiculous statements to me, only your posts seem to be doing that.
Um, Mr Richard didn't quote me calling him a liar, did he? It wasn't about last few posts in this thread. Or do you mean Mr Heathfield is liar? Then, I didn't mean Eric words. I said "Mr Heathfield". What I said to Mr Richard has nothing to do with what I said to Eric Sosman.
I've never noticed either Richard Heathfield or Eric lying. I've seen
them make mistakes, and I've certainly disagreed with Richard in the
past (I don't keep score, but he has probably been right more often than
me). However the way you have been attacking in this thread I can
certainly see how what you've said can be interpreted as implying they
are lying, in particular what you say above about Eric's comment.
Um, I am attacking, huh? Okay.
>
>>>Hm, somehow I don't believe you're most offended by me calling you a liar. For some reasons I think the worst thing is disagreement with you even after you present all your killer 100%-correct-and-ignore-everything-else arguments. Did I just call you a liar again? Sorry about that, I do understand I will be hurt by this more than you.
Whether Richard and Eric feel offended or hurt does not change whether it is an offensive thing to say.
So it's fine for Eric to insult other people by calling them incompetent, but it was so bad from me to say an offensive thing?
The evidence you present suggests that they are incompetent.
Bullshit.
Yevgen Muntyan wrote:
>
.... snip ...
>
You didn't get it either.
#include <foo-thelib.h>
#define _GNU_SOURCE
#include <string.h>
void bar (void)
{
strndup ("33", 1);
}
If foo.h includes string.h, then strndup() won't be declared.
Whose problem is this? User's. Why does it happen? Because
user is stupid, he should #define _GNU_SOURCE at the very
beginning. Is the library right? No.
If your mythical user includes the "#define _GNU_SOURCE" line he is
a known C idiot, who is invading the implementors namespace and
ensuring that overall behaviour is undefined.
--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
--
Posted via a free Usenet account from http://www.teranews.com
CBFalconer <cb********@yahoo.comwrites:
Yevgen Muntyan wrote:
>>
... snip ...
>> You didn't get it either.
#include <foo-thelib.h> #define _GNU_SOURCE #include <string.h>
void bar (void) { strndup ("33", 1); }
If foo.h includes string.h, then strndup() won't be declared. Whose problem is this? User's. Why does it happen? Because user is stupid, he should #define _GNU_SOURCE at the very beginning. Is the library right? No.
If your mythical user includes the "#define _GNU_SOURCE" line he is
a known C idiot, who is invading the implementors namespace and
ensuring that overall behaviour is undefined.
He's not necessarily an idiot. He is very likely just using the
documented mechanism to enable glibc-specific extensions to the
standard C library. The macro "_GNU_SOURCE" is specified in the glibc
documentation; since glibc is part of the implementation, using a name
in the implementor's namespace is exactly the right thing for glibc to
do.
Yes, the behavior is undefined by the standard. Exploiting undefined
behavior (by defining it) is a perfectly good way to implement
extensions.
Of course the user needs to know how to use it properly, and in
particular whether it should appear before or after any other #include
directives.
--
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."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Yevgen Muntyan wrote, On 16/03/07 18:49:
Flash Gordon wrote:
>Yevgen Muntyan wrote, On 16/03/07 15:26:
>>Flash Gordon wrote: Yevgen Muntyan wrote, On 16/03/07 06:22:
[snip]
>>>>Dear Mr Heathfield, I do understand that saying in public you're not telling the truth is a bad offense. But when you're making totally ridiculous statements to justify your rudeness, I simply can't resist.
The last few posts in this thread by Richard and Eric do not seem to be making ridiculous statements to me, only your posts seem to be doing that.
Um, Mr Richard didn't quote me calling him a liar, did he? It wasn't about last few posts in this thread. Or do you mean Mr Heathfield is liar? Then, I didn't mean Eric words. I said "Mr Heathfield". What I said to Mr Richard has nothing to do with what I said to Eric Sosman.
I've never noticed either Richard Heathfield or Eric lying. I've seen them make mistakes, and I've certainly disagreed with Richard in the past (I don't keep score, but he has probably been right more often than me). However the way you have been attacking in this thread I can certainly see how what you've said can be interpreted as implying they are lying, in particular what you say above about Eric's comment.
Um, I am attacking, huh? Okay.
Saying something like,
| Perhaps. I do understand that you have to earn right to be an asshole,
| like Mr Heathfield has.
Certainly sounds like attacking to me.
Reviewing the thread, it looks like there are only a couple of instances
of such things, so it might in part be you catching me on the wrong day
or me finding you irritating for whatever reason.
>>>>Hm, somehow I don't believe you're most offended by me calling you a liar. For some reasons I think the worst thing is disagreement with you even after you present all your killer 100%-correct-and-ignore-everything-else arguments. Did I just call you a liar again? Sorry about that, I do understand I will be hurt by this more than you.
Whether Richard and Eric feel offended or hurt does not change whether it is an offensive thing to say.
So it's fine for Eric to insult other people by calling them incompetent, but it was so bad from me to say an offensive thing?
The evidence you present suggests that they are incompetent.
Bullshit.
Suggesting that they are avoiding the standard headers because they
think some implementation has headers broken enough that they have to be
avoided does suggest they are incompetent. However, elsewhere you have
admitted that it is glibc and looking at the headers in some of them
they *do* include stdef.h and stdio.h, so that obviously is *not* the
reason.
--
Flash Gordon
Flash Gordon wrote:
Yevgen Muntyan wrote, On 16/03/07 18:49:
>Flash Gordon wrote:
>>Yevgen Muntyan wrote, On 16/03/07 15:26: Flash Gordon wrote: Yevgen Muntyan wrote, On 16/03/07 06:22:
[snip]
>>>>>Dear Mr Heathfield, I do understand that saying in public you're not >telling the truth is a bad offense. But when you're making totally >ridiculous statements to justify your rudeness, I simply can't >resist. > The last few posts in this thread by Richard and Eric do not seem to be making ridiculous statements to me, only your posts seem to be doing that.
Um, Mr Richard didn't quote me calling him a liar, did he? It wasn't about last few posts in this thread. Or do you mean Mr Heathfield is liar? Then, I didn't mean Eric words. I said "Mr Heathfield". What I said to Mr Richard has nothing to do with what I said to Eric Sosman.
I've never noticed either Richard Heathfield or Eric lying. I've seen them make mistakes, and I've certainly disagreed with Richard in the past (I don't keep score, but he has probably been right more often than me). However the way you have been attacking in this thread I can certainly see how what you've said can be interpreted as implying they are lying, in particular what you say above about Eric's comment.
Um, I am attacking, huh? Okay.
Saying something like,
| Perhaps. I do understand that you have to earn right to be an asshole,
| like Mr Heathfield has.
Certainly sounds like attacking to me.
This indeed does. I didn't understand you mean "attacking Mr.
Heathfield". Well, he came accusing me of calling him a liar, and
did not present any evidence of that. Ask him when I called him a
liar. Maybe you'll understand why I feel this way about him. Or
perhaps not. Or perhaps you'll be presented an evidence of him being
an asshole.
Reviewing the thread, it looks like there are only a couple of instances
of such things, so it might in part be you catching me on the wrong day
or me finding you irritating for whatever reason.
>>>>>Hm, somehow I don't believe you're most offended by me calling you >a liar. For some reasons I think the worst thing is disagreement >with you even after you present all your killer >100%-correct-and-ignore-everything-else arguments. Did I just call >you a >liar again? >Sorry about that, I do understand I will be hurt by this more than >you. > Whether Richard and Eric feel offended or hurt does not change whether it is an offensive thing to say.
So it's fine for Eric to insult other people by calling them incompetent, but it was so bad from me to say an offensive thing?
The evidence you present suggests that they are incompetent.
Bullshit.
Suggesting that they are avoiding the standard headers because they
think some implementation has headers broken enough that they have to be
avoided does suggest they are incompetent.
I did *not* say glib avoids using standard headers. It does not, in
fact. It does avoid string.h, but it doesn't avoid stddef.h. If you
think otherwise, please quote where I said glib uses unsigned long
instead of size_t because of headers thing.
Glib uses unsigned long there because of other reasons, which I
suspect are really "historic reasons". You and Eric easily jump
into "glib developers are incompetent". This is what I call bullshit,
or, politely, groundless, not honest and hostile.
Yevgen
CBFalconer wrote:
Yevgen Muntyan wrote:
... snip ...
>You didn't get it either.
#include <foo-thelib.h> #define _GNU_SOURCE #include <string.h>
void bar (void) { strndup ("33", 1); }
If foo.h includes string.h, then strndup() won't be declared. Whose problem is this? User's. Why does it happen? Because user is stupid, he should #define _GNU_SOURCE at the very beginning. Is the library right? No.
If your mythical user includes the "#define _GNU_SOURCE" line he is
a known C idiot,
Or he reads documentation of his implementation and wants to
use nice convenient strndup() function without having to
reimplement it? Use in *legal* *documented* ways. Try
man 3 strndup if you have access to a linux machine.
Sure, great brave C.Falconer will just implement string functions
he likes to implement so much and just call idiots everybody
who doesn't do so. Or what? See, I just noticed you called
me an idiot (no, I didn't use strndup, I used this stupid
#define when needed to get lstat() declared in strict ansi mode,
which is buggy in gcc+glibc). Should I get insulted and run away
crying? Chuck said! Sure!
Yevgen
Yevgen Muntyan wrote, On 16/03/07 16:12:
Flash Gordon wrote:
>Yevgen Muntyan wrote, On 16/03/07 03:57:
>>Eric Sosman wrote: Yevgen Muntyan wrote: Eric Sosman wrote: >Yevgen Muntyan wrote: >>This Win64 thing is funny, because no other 'popular' system >>has small long type. Good or bad, but lot of useful software is >>written >>under many assumptions like 8-bit bytes, ASCII, long >= size_t. >>Simply >>ignoring it won't always work since you might actually need that >>software (you know, libraries which have useful stuff). >> > Do you have a specific library in mind, or are you "just >supposing?" If the latter, drop it until the situation actually >arises. If the former, please tell us about it so we'll be warned >not to use that organization's products. > I do have a specific library in mind, indeed. It's not written by me or my friends or relatives. It's a widely used and indeed useful library.
... which you have not named, to warn us away from it.
That's right. Somehow I don't believe you. And somehow I don't want bring names in this context. Those guys are not hostile, unlike you.
If you are not prepared to provide evidence for you claims then do not expect people to take them seriously.
For what claim exactly? That there is such a library?
Yes.
Are you calling me
a liar? And no, I don't want to bring names in this context, regardless
of how people take my claims. Especially if they don't take them
seriously regardless.
If you say something exists but you are not prepared to tell people your
references you cannot expect to be taken seriously.
You know, if I am accused of asking standard to
bless using UB (read the thread if you like), then I can be said to fly
to Mars and whatnot. And then what?
I did not comment on that part of the argument because I did not want to
trace it back.
>>>>> Proposition: There is *no* reason to use unsigned long instead >of size_t. None. Nada. Zero. Zip. Nulla. > I know none, this is true. You seem to know none. You sure there *isn't* one?
I offered the remark as a "proposition," thus inviting a counter-example. Got one?
Nope, as I said. Still can't make a conclusion there isn't one. I don't know way too many things to claim something doesn't exist because I've never seen it.
So because others here can't think of a good reason to use long instead of size_t and you can't prove there is never such a reason, we must all assume there could be a good reason to not use the mechanisms provided by the standard to deal with a problem?
I think you have it not even backwards. I said that some people *may*
have good reasons. If you say that fact of you, Eric, me, and two
other people not knowing such a good reason implies non-existence of
such a reason, then I will disagree.
But in fact, I was trying to make up reasons "why people would not
want to have standard headers included in their own headers which
do not use features from standard headers". It's in fact even not
very relevant to the "evil library", because it has dedicated type
to serve same purpose as size_t, and long instead of size_t was
in fact a mistake, and then there is backwards compatibility, api
stability and all that.
The version of the library originally introducing long instead of size_t
is the "evil library" so you still have it.
Also library frequently break backwards compatibility in various ways on
major upgrades.
But you folks decided I am defending this particular thing, and
to justify that I accuse standard of causing all my problems. It
surely is easier to argue with.
The thing that got me was you appearing to be claiming that an
implementation with broken headers was a good reason to avoid including
them and therefore not having size_t available.
>I think you have it backwards. If you are claiming there is a reason to avoid the mechanisms the standard provides to allow portability then it is up to *you* to prove your point, not up to others to disprove it.
I am claiming this: my (and yours, and Eric's, and all the regulars
here) lack of knowledge about one particular obscure system does
*not* imply I (you, Eric, etc.) *know* something about it. If
I write code, I don't worry about those obscure systems. But I
admit a possibility of someone who does worry about obscure system
I never heard about. I do *not* claim existence of that system.
Not sure what I need to prove here.
The point of using the facilities provided by the standard headers is so
that you do not have to worry about obscure systems since the
implementer has done the worrying for you.
>>>>>Every module that >performs I/O includes <stdio.hand has size_t defined; > Unless this module use third-party I/O routines, or uses things like open/write. I.e. no, not every.
Yes, "every"
Good you used "quotes" here.
Probably for emphasis.
I doubt it. Read the sentence. "Every module that performs I/O includes
<stdio.h>". It is not true. "Every" was put in quotes to make it "true".
>I've never had to include a header just to get size_t when I wanted it because I've somehow always without thinking included a header (or more than one) that provides it.
Same thing. I rarely use size_t in fact. I did though have modules
which perform I/O and do not use stdio.h.
So you are using things outside of standard C. Now what would be broken
if you included one of the standard headers?
>>>-- unless you've decided to stray outside the bounds of Standard C. There are good reasons for such strayings, but you can hardly blame the consequences on the Standard headers.
If the headers in particular implementation are broken, then they are broken. I don't blame the Standard for that. Not sure if I blame "Standard headers". And not sure how it is relevant to whether I use or do not use POSIX read and write.
Yet you are using broken headers and headers providing extensions (all your examples being ones the standard allows them to do that will not break any otherwise correct code) as a reason for not including them. Broken headers is not a good reason to not use them since if you cannot rely on the C implementation you cannot rely on it and need to use a different one instead.
This is a very wrong thing. There may be localized bugs which have
to be worked around. It's a source distribution world, you can't
say "Fnu compiler is broken, we shall not use it", you have to
work it around if it's not too hard. Seen gnulib?
Yes, I've seen it. It does not seem to mention support for broken
implementations, although it does provide stuff for pre-C89 implementations.
>>>>Anyway, these three examples are examples of why *user* would use the standard headers. The library itself may not need them. Now, it may be important for the user how he uses the standard headers: what he #define's or in what order he uses the headers, or whatever. Library has no business in that.
Again, I'd be interested to learn the name of this perverse library you keep alluding to.
Proposition: A library that deals in object sizes but uses unsigned long instead of size_t to describe them is perverse. Counter-example?
I know one. If a library has a bug, you call it perverse? I know *lots*.
Provide ONE specific example where a library has a broken header (give the name and version of the library) which is bad enough to cause problems with otherwise correct code.
So you can all jump around and yell "those guys are incompetent morons
how cool we are"?
No, to make the point.
>>>>Now, if it's true that one single standard header ever caused problems, then library developers have really good reason to avoid standard headers altogether.
Balderdash. They should be equally leery of the % operator.
I'd think the developers carefully use % operator if it's broken on some target platform. Is it broken somewhere, did it cause problems for someone? You seem to imply it.
1+1 is broken on at least one implementation (well, it was something fundamental like that), should we avoid adding that as a result?
If your code is going to work on that implementation, yes.
Actually, when it was found that the Pentium (I think it was) had a bug
like this there was a major shout about it and MS release a new version
of their compiler (their C implementation was effectively broken by it)
that worked around the processor bug thus leading to a non-broken
implementation. So yes, all the writers of software (or enough) shouted
and screamed about the C implementation now being broken and waited for
it to be fixed instead of working around the problem themselves.
>No, you file a bug report on the library (or processor in this case) and tell your user base not to use it because it is broken.
Totally funny.
I was not one to raise bug reports on the Pentium, but people *did* and
it got fixed but providers of implementations providing implementations
that worked despite the processor bug and Intel fixing the processor.
What I have done is told customers that given versions of libraries were
broken and that they had to upgrade. I've also told them that they have
to upgrade to newer version of complete OSs. My customers are orders of
magnitude larger than the company I work for.
>I know, because I work in a commercial organisation and we *do* tell them that they cannot use certain things with our software because they are broken.
Well, it's different world. You can't say "don't use glibc" or
"don't use FreeBSD C library" or "don't use operating system
you're using".
I can do it. I know because I HAVE done it. Let's see if I can remember
it...
We told customers they had to upgrade to SCO 5.0.5 because the Java
implementations available for earlier versions were not good enough...
We later told them that they had to upgrade from SCO to Linux because
SCO various libraries we wanted to use were not available on SCO...
We also told another that they would have to upgrade from AIX 4.3 to
either Linux or an up to date version of AIX due to library problems...
We have also told customers when they have reported problems and we have
seen that their systems were out of date to "patch up to the latest
version and test again, if there is still a problem we will look at it
then." So they had to update before we would even look to see if the
problem was in out software or the library!
>>>>Somehow you started talking like I am saying "I don't want to use standard headers in my program". Nope.
Your argument (perhaps I have misunderstood it) was that someone might prefer to use unsigned long instead of size_t because he would need to include a Standard header to obtain a size_t definition, and the implementation's headers might be broken. That's what I think you said; that's what I reject.
Well, I can't provide any examples of broken standard headers, I have access only to two systems here, and I am not aware of some famous example. Does it mean there isn't one? No. Is there one? I have no idea. Do *I* avoid using standard headers? *No*. Read the paragraph you replied to?
The contention of everyone else
"everyone else" is three people including you? Perhaps you are right,
I don't know. But I don't know enough to make such a conclusion.
Any such implementation would be basically unusable so it would not survive.
>is that there is no implementation worth bothering with that has headers sufficiently broken to be worth worrying about. There is a very good reason for this, and such implementation would be well publicised and boycotted until it was fixed,
You are kidding, right? How about MS?
When building with Visual Studio in include their standard headers
without any problems. So what about MS? They are not an example of such
a broken system.
Oh, of course, you stopped generalizing and now you are talking about
size_t. Yes, I can't believe there is an implementation which doesn't
have size_t correctly defined in stddef.h. I somehow talked about
the general thing of people not wanting to use standard headers.
You can read it upthread.
I claim that there has been no implementation since 1995 claiming
conformance to any version of the C standard that has been broken for as
long as a month such that including the standard headers in conforming
mode would break correct code. I further claim that even in
non-conforming mode if you avoid anything that clashes with documented
extensions it would still not break.
I am *not* talking specifically about size_t, I am talking about
including *any* standard header.
>so a short time after it is released it will be of historic interest only because the free bugfix will be available.
Again, it is up to *you* to prove your contention that there are reasons to avoid standard headers due to problems,
I can't prove it, and I am not going to, since I simply don't know
if it's true. But I don't claim it's false just because I don't know
any example.
I do claim it is true because I have some limited understanding of
commercial and open-source realities. The reality is that no one can be
bothered to deal with severely broken systems unless they are being paid
a lot of money specifically to do it. So any implementation broken badly
enough that including standard headers is not safe will simply not be used.
>because the purpose of the standard is to provide you with the guarantees that you do not need to worry about such things.
>>>>>Do you provide a mian() >function just in case the implementation has a spelling error? > Ever heard of WinMain() thing? No, I don't provide mian() function. I also don't eat spoons, and I don't fly.
Yes, I've heard of the WinMain() thing. It's perfectly legal, but only for free-standing (not hosted) environments. In those systems, the entire Standard library is optional and you cannot even rely on the existence of exit(). Those systems do not meet the requirements the Standard places on hosted systems, and if they claim to conform to the Standard for hosted systems they claim incorrectly.
I'm glad you provided this useful information, even though it's irrelevant.
It is entirely relevant since it shows that your suggesting WinMain as a counter-example was *not* a valid counter-example.
You mean "mian" was relevant to anything?
Yes. If an implementation is so broken that including standard headers
is not safe then it is so broken that anything could be wrong including
the spelling of main.
> But since we're on it, implementation may provide a separate translation unit which contains definition of main(), which in turn calls my WinMain.
It can't if it is a hosted implementation.
Yes it can, why can't it? Execution starts in main(), everything
is fine.
If you cannot write your own main function and have that as the entry
point for your program then by *definition* it is not a conforming
hosted implementation.
>It is actually well known that when compiling applications for the Window GUI using MS VC++ you are using a freestanding implementation.
With MS VC++ maybe. I can use other compilers which *might* use
hidden main(). Can you *prove* (you love proofs don't you) my
favorite compiler doesn't do what I say? (I have no idea what
it does really)
The proof is the definition of a hosted implementation given by the C
standard. It states that the entry point to the program that *you* write
is main, so if the entry point to your code is anything other than main
it does not meet that definition.
> I can ask implementation to do it for me, and it'd be perfectly legal. I have no idea how exactly it's done in MS implementation, do you? Come on, let's talk about what's legal and what's not, exactly on point.
WinMain is legal because it is a FREESTANDING implementation, all appearances to the contrary. When you invoke MS VC++ as a hosted implementation *you* have to provide main, so it is not a counter example.
Again, I don't know how to use MS VC++.
That I can believe. A lot of people don't know how to use it properly as
a C compiler. My statement is still true.
>>>>> As for standard headers providing non-Standard definitions: >First, there are identifiers that are reserved for future use, >meaning that the standard headers are free to define them if >they so choose. You are not allowed to use `isosceles' as an >identifier with external linkage, and if you do use it you are at >fault and not the headers. > Good or bad, but: > NAME strdup, strndup, strdupa, strndupa - duplicate a string SYNOPSIS #define _GNU_SOURCE #include <string.h> > char *strndup(const char *s, size_t n); > It's not (other) library developers business how user is going to use strndup, it's personal matter between user and his C library.
Um, er, haven't you simply illustrated what I wrote? "There are identifiers that are reserved for future use, meaning that the standard headers are free to define them." The four strxxx() identifiers you show are in that class: The implementation is at liberty to provide them, and if you use `strdup' or `streptomycin' as an identifier, the clash is your fault, not the implementation's. "Personal matters" have nothing to do with it: You either tread on the reserved name space and risk the consequences, or you keep your distance and remain safe.
Sorry, what clash?
That is the point. If you (and this mythical library that has to avoid use of standard headers) do not invade the implementation namespace then there is no clash, so the headers declaring strdup is not a problem. If you or the mythical third party library do then it is *your* code, or that mythical library, that is broken *not* the standard header.
You didn't get it either.
#include <foo-thelib.h>
#define _GNU_SOURCE
#include <string.h>
void bar (void)
{
strndup ("33", 1);
}
If foo.h includes string.h, then strndup() won't be declared.
Whose problem is this? User's. Why does it happen? Because
user is stupid, he should #define _GNU_SOURCE at the very
beginning. Is the library right? No.
Actually, I believe that if you do:
#define _GNU_SOURCE
#include <foo-thelib.h>
#include <string.h>
void bar (void)
{
strndup ("33", 1);
}
It will all work perfectly unless foo-thelib.h invades the
implementation name space, in which case foo-thelib.h is broken. The
implementation provided headers are perfectly OK.
> And this is exactly the business for me, a user, not for library to decide which headers, in what order, and how I use. (_GNU_SOURCE and strndup is simply a trivial example, people say there are much worse situations where header order matters)
y People say the earth is flat, that does not make it true. People also say the earth is not flat, and them saying that does not make it true either.
It's not about the truth. It's about you not having right to tell others
people earth is round (it's not, you know).
Freedom of speech. I've got the right to tell you that. Equally you have
the right to tell me that I am wrong. However, that is not what is
important here. What is important is what is true and what isn't, if you
don't think that then I think a technical group is the wrong place for you.
>>But even if I wrote totally illegal code which worked fine, it'd be stupid if some unrelated library broke it. It would be totally fine as far as the standard is concerned, of course, UB and all that, so what?
For the record, I am not saying I am writing that evil code, nor am I advocating writing it. (I know, it can't help, you'll think I ask standard for something, moreover you will think I ask you for something, and so on)
You are advocating that there are good reasons to write stupidly broken code when writing a library,
Am I?
That's how it seemed.
>everyone else is saying you are wrong. If you want to convince anyone that you are correct, or even that you have a valid if mistaken point of view, then *you* have to provide some concrete example, not hand waving and saying you know this library that does it and you are sure that it is because of broken headers and they have a good reason.
>>> ...
>Second, if you define reserved identifiers >like _GNU_SOURCE you invoke undefined behavior. You may *want* >the undefined behavior, > See above, SYNOPSIS section.
As I said, you may want the undefined behavior.
I may want the well-defined behavior which left undefined by the standard. If the use of _GNU_SOURCE is documented by implementation, I may use it. But it's not the point of course.
That's one of those "personal matters" you refer to, but not a problem for C.
Who said it's a problem for C. Again, you are saying it like I am claiming standard owes me something, standard is completely wrong, and I invoke UB every day twice a day. No, I am saying that library developers may have an attitude of "user knows better what he's doing".
You are saying that the writer of a third party library has to do something everyone else considers stupid to prevent it being broken when you do something legal on a specific implementation. I say this is complete rubbish and the writer of the third party library should use the standard mechanisms provided. Either proved *real* *verifiable* evidence of your claim that there are good reasons or accept that the writers of that library have done the wrong thing.
Still, I can't do either. I can't accept something has done a wrong
thing simply because I don't know the reason he did it.
Another good reason for providing what you believe are example. Then
people can explain why it was wrong or be convinced that there actually
is a good reason under some situation.
If you can
it's your right. Of course, your opinion is backed up by opinions
of other three people in this newsgroup, of yeah, collective wisdom.
Just tell, why does gnulib exist, why does it have so many wrappers
for so many *standard* things? Because people working on it are
stupid?
It exists to aid porting GNU, part of which *is* an implementation.
There are specific reasons why it still supports pre-C89 implementations
(actually, it is only the library they support as pre-C89). An
implementation no having been upgraded to C89 is not broken as such,
just old (or, rather, ancient), but supporting it requires wrapping
various standard library functions and dealing with not having standard
headers, or them not having been upgraded to match the C89 standard.
So it is *not* an example of working around broken implementations, only
an example of comparability with ancient systems, and they are slowly
moving the goal posts forward.
It also wraps some functions to provide consistent behaviour where the
standard does not require it, for example wrapping malloc so that their
wrapped version when passed a size of 0 will try to allocate a byte and
so return a non-NULL value if possible.
The documentation for gnulib also talks about the fact that it *can*
freely include the standard headers that are available in the oldest
implementation that is supports, so it is definitely *not* an example of
dealing with not being able to include the headers because they are too
broken.
--
Flash Gordon
Flash Gordon <sp**@flash-gordon.me.ukwrites:
[...]
Suggesting that they are avoiding the standard headers because they
think some implementation has headers broken enough that they have to
be avoided does suggest they are incompetent. However, elsewhere you
have admitted that it is glibc and looking at the headers in some of
them they *do* include stdef.h and stdio.h, so that obviously is *not*
the reason.
<OT>
I think he said he's talking about glib, not glibc. glib and glibc
are two different things. glibc is the GNU implementation of the
standard C library. glib is "the low-level core library that forms
the basis of GTK+ and GNOME".
</OT>
--
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."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Flash Gordon wrote:
Yevgen Muntyan wrote, On 16/03/07 16:12:
>Flash Gordon wrote:
>>Yevgen Muntyan wrote, On 16/03/07 03:57:
....
You know, if I am accused of asking standard to bless using UB (read the thread if you like), then I can be said to fly to Mars and whatnot. And then what?
I did not comment on that part of the argument because I did not want to
trace it back.
Right... You commented on parts you liked, and you don't care about
the discussion in whole, where I say one thing and other hears what
he wants to hear. Just like here, you're saying I am claiming there
is a reason not to use standard headers. While I said like five times
that I do *not* know such a reason. Of course, from my unwillingness
to make baseless conclusions you make a conclusion that my opinion
is the contrary. And so on.
.....
>But you folks decided I am defending this particular thing, and to justify that I accuse standard of causing all my problems. It surely is easier to argue with.
The thing that got me was you appearing to be claiming that an
implementation with broken headers was a good reason to avoid including
them and therefore not having size_t available.
It was a hypothetical good reason for not using standard headers
in general, which naturally leads to avoiding #includ'ing stddef.h.
But yes, I do support the following: if an implementation has broken
header foobar.h and I write code for that platform, I will try to work
it around; and if not using foobar.h is a fix, I will avoid using
foobar.h. And *no*, I do not avoid using standard headers in *my*
code because of hypothetical problems.
>>I think you have it backwards. If you are claiming there is a reason to avoid the mechanisms the standard provides to allow portability then it is up to *you* to prove your point, not up to others to disprove it.
I am claiming this: my (and yours, and Eric's, and all the regulars here) lack of knowledge about one particular obscure system does *not* imply I (you, Eric, etc.) *know* something about it. If I write code, I don't worry about those obscure systems. But I admit a possibility of someone who does worry about obscure system I never heard about. I do *not* claim existence of that system. Not sure what I need to prove here.
The point of using the facilities provided by the standard headers is so
that you do not have to worry about obscure systems since the
implementer has done the worrying for you.
Indeed, that's why we should use standard headers. And? Was it
you agreed or disagreed with my words about making conclusion
without having enough ground?
>>>>>>Every module that >>performs I/O includes <stdio.hand has size_t defined; >> >Unless this module use third-party I/O routines, or uses things like >open/write. I.e. no, not every. > Yes, "every"
Good you used "quotes" here.
Probably for emphasis.
I doubt it. Read the sentence. "Every module that performs I/O includes <stdio.h>". It is not true. "Every" was put in quotes to make it "true".
>>I've never had to include a header just to get size_t when I wanted it because I've somehow always without thinking included a header (or more than one) that provides it.
Same thing. I rarely use size_t in fact. I did though have modules which perform I/O and do not use stdio.h.
So you are using things outside of standard C. Now what would be broken
if you included one of the standard headers?
If *I* did, nothing would break. You can prove there are no weird things
in stdio.h like that strndup on every system? You can prove silent
#includ'ing stdio.h will not break user code?
>>>>-- unless you've decided to stray outside the bounds of Standard C. There are good reasons for such strayings, but you can hardly blame the consequences on the Standard headers.
If the headers in particular implementation are broken, then they are broken. I don't blame the Standard for that. Not sure if I blame "Standard headers". And not sure how it is relevant to whether I use or do not use POSIX read and write.
Yet you are using broken headers and headers providing extensions (all your examples being ones the standard allows them to do that will not break any otherwise correct code) as a reason for not including them. Broken headers is not a good reason to not use them since if you cannot rely on the C implementation you cannot rely on it and need to use a different one instead.
This is a very wrong thing. There may be localized bugs which have to be worked around. It's a source distribution world, you can't say "Fnu compiler is broken, we shall not use it", you have to work it around if it's not too hard. Seen gnulib?
Yes, I've seen it. It does not seem to mention support for broken
implementations, although it does provide stuff for pre-C89
implementations.
Yes it does support broken C99 implementations. Now you can say
something about C90, that gnulib example is irrelevant since C90
is the important thing, perhaps because C90 is widely implemented
and so on. And we're back to Win64. Oh, totally forgot, it also
supports some broken C90 implementations.
....
>>Provide ONE specific example where a library has a broken header (give the name and version of the library) which is bad enough to cause problems with otherwise correct code.
So you can all jump around and yell "those guys are incompetent morons how cool we are"?
No, to make the point.
Sorry, I misread what you said. What did you ask? What library and what
header? I know an implementation which breaks correct code, and it was
the original thing. I know a library which conforms to C90 and works
on all computers out there (even with C99 since no sane implementation
has small long) but Win64.
>>>>>Now, if it's true that one single standard header ever caused >problems, then library developers have really good reason to avoid >standard headers altogether. > Balderdash. They should be equally leery of the % operator.
I'd think the developers carefully use % operator if it's broken on some target platform. Is it broken somewhere, did it cause problems for someone? You seem to imply it.
1+1 is broken on at least one implementation (well, it was something fundamental like that), should we avoid adding that as a result?
If your code is going to work on that implementation, yes.
Actually, when it was found that the Pentium (I think it was) had a bug
like this there was a major shout about it and MS release a new version
of their compiler (their C implementation was effectively broken by it)
that worked around the processor bug thus leading to a non-broken
implementation. So yes, all the writers of software (or enough) shouted
and screamed about the C implementation now being broken and waited for
it to be fixed instead of working around the problem themselves.
I'm afraid processor bug is a little different from software bugs.
Broken string functions on some platforms come to mind. Glib has
some stuff to work that around.
>>No, you file a bug report on the library (or processor in this case) and tell your user base not to use it because it is broken.
Totally funny.
I was not one to raise bug reports on the Pentium, but people *did* and
it got fixed but providers of implementations providing implementations
that worked despite the processor bug and Intel fixing the processor.
What I have done is told customers that given versions of libraries were
broken and that they had to upgrade. I've also told them that they have
to upgrade to newer version of complete OSs. My customers are orders of
magnitude larger than the company I work for.
Good for you, what can I say? Not all people are so lucky, and not all
bugs are processor bugs which are so serious that addition breaks.
>>I know, because I work in a commercial organisation and we *do* tell them that they cannot use certain things with our software because they are broken.
Well, it's different world. You can't say "don't use glibc" or "don't use FreeBSD C library" or "don't use operating system you're using".
I can do it. I know because I HAVE done it. Let's see if I can remember
it...
We told customers they had to upgrade to SCO 5.0.5 because the Java
implementations available for earlier versions were not good enough...
We later told them that they had to upgrade from SCO to Linux because
SCO various libraries we wanted to use were not available on SCO...
We also told another that they would have to upgrade from AIX 4.3 to
either Linux or an up to date version of AIX due to library problems...
We have also told customers when they have reported problems and we have
seen that their systems were out of date to "patch up to the latest
version and test again, if there is still a problem we will look at it
then." So they had to update before we would even look to see if the
problem was in out software or the library!
Again, great for you. Really great and I am glad you can workaround
problems by making them not exist in the first place. If you're saying
it's always possible and easy, you're wrong.
>>>Well, I can't provide any examples of broken standard headers, I have access only to two systems here, and I am not aware of some famous example. Does it mean there isn't one? No. Is there one? I have no idea. Do *I* avoid using standard headers? *No*. Read the paragraph you replied to?
The contention of everyone else
"everyone else" is three people including you? Perhaps you are right, I don't know. But I don't know enough to make such a conclusion.
Any such implementation would be basically unusable so it would not
survive.
Such as what exactly? Are you saying implementation with a bug
in a standard header can't survive? I doubt it. Depends on the
bug, doesn't it? Or maybe you're saying there are no implementations
with buggy headers?
>>is that there is no implementation worth bothering with that has headers sufficiently broken to be worth worrying about. There is a very good reason for this, and such implementation would be well publicised and boycotted until it was fixed,
You are kidding, right? How about MS?
When building with Visual Studio in include their standard headers
without any problems. So what about MS? They are not an example of such
a broken system.
Um, Win64? Will it be boycotted for making small long type? Or does
it depend on the bug severity?
>Oh, of course, you stopped generalizing and now you are talking about size_t. Yes, I can't believe there is an implementation which doesn't have size_t correctly defined in stddef.h. I somehow talked about the general thing of people not wanting to use standard headers. You can read it upthread.
I claim that there has been no implementation since 1995 claiming
conformance to any version of the C standard that has been broken for as
long as a month such that including the standard headers in conforming
mode would break correct code. I further claim that even in
non-conforming mode if you avoid anything that clashes with documented
extensions it would still not break.
_GNU_SOURCE thing? No clashes. Or do you mean standard C code? Who
said there are problems with that? See, library (not the C library)
developers may care about non-standard user code.
....
>>Again, it is up to *you* to prove your contention that there are reasons to avoid standard headers due to problems,
I can't prove it, and I am not going to, since I simply don't know if it's true. But I don't claim it's false just because I don't know any example.
I do claim it is true because I have some limited understanding of
commercial and open-source realities.
Especially open-source it seems.
The reality is that no one can be
bothered to deal with severely broken systems unless they are being paid
a lot of money specifically to do it. So any implementation broken badly
enough that including standard headers is not safe will simply not be used.
Perhaps. Or perhaps not. You seem to be talking about standard
programs which use only standard headers or at least use only
standard features from standard headers. You sure every implementation
has its implementation-specific extensions done in good nice
way so you can be sure #includ'ing a standard header behind
user back is safe if user uses those funny extensions?
....
>You mean "mian" was relevant to anything?
Yes. If an implementation is so broken that including standard headers
is not safe then it is so broken that anything could be wrong including
the spelling of main.
See? Same thing. From "a header may break user code" you make conclusion
"a standard header may break standard code", though I didn't say that
and my example with _GNU_SOURCE isn't standard.
>> But since we're on it, implementation may provide a separate translation unit which contains definition of main(), which in turn calls my WinMain.
It can't if it is a hosted implementation.
Yes it can, why can't it? Execution starts in main(), everything is fine.
If you cannot write your own main function and have that as the entry
point for your program then by *definition* it is not a conforming
hosted implementation.
Who said I can't write my main() function? I can. Or I can ask
implementation to get me builtin translation unit with main()
which would call my FooBarMain().
>>It is actually well known that when compiling applications for the Window GUI using MS VC++ you are using a freestanding implementation.
With MS VC++ maybe. I can use other compilers which *might* use hidden main(). Can you *prove* (you love proofs don't you) my favorite compiler doesn't do what I say? (I have no idea what it does really)
The proof is the definition of a hosted implementation given by the C
standard. It states that the entry point to the program that *you* write
is main, so if the entry point to your code is anything other than main
it does not meet that definition.
And if entry point is indeed main()? Here, let me repeat:
>I can use other compilers which *might* use hidden main(). Can you *prove* (you love proofs don't you) my favorite compiler doesn't do what I say? (I have no idea what it does really)
>> I can ask implementation to do it for me, and it'd be perfectly legal. I have no idea how exactly it's done in MS implementation, do you? Come on, let's talk about what's legal and what's not, exactly on point.
WinMain is legal because it is a FREESTANDING implementation, all appearances to the contrary. When you invoke MS VC++ as a hosted implementation *you* have to provide main, so it is not a counter example.
Again, I don't know how to use MS VC++.
That I can believe. A lot of people don't know how to use it properly as
a C compiler. My statement is still true.
I have no idea how to use it properly as a Foo or C++ compiler either.
Nice nit though. Your statement is probably true, I don't really
have doubts about it.
....
>If foo.h includes string.h, then strndup() won't be declared. Whose problem is this? User's. Why does it happen? Because user is stupid, he should #define _GNU_SOURCE at the very beginning. Is the library right? No.
Actually, I believe that if you do:
#define _GNU_SOURCE
#include <foo-thelib.h>
#include <string.h>
void bar (void)
{
strndup ("33", 1);
}
It will all work perfectly unless foo-thelib.h invades the
implementation name space, in which case foo-thelib.h is broken. The
implementation provided headers are perfectly OK.
That's right, that's why I said "user is stupid". So, a third-party
library mandates that stupid things are user's problem. It's quite
sensible, and in fact it's an approach taken by many libraries (glib
too). Now, can you guarantee there are no totally-legitimate non-stupid
things like this _GNU_SOURCE thing which could break? Not necessarily
with standard C headers by the way. sys/stat.h is good too to make
developers wary of standard headers.
....
>>People say the earth is flat, that does not make it true. People also say the earth is not flat, and them saying that does not make it true either.
It's not about the truth. It's about you not having right to tell others people earth is round (it's not, you know).
Freedom of speech. I've got the right to tell you that.
Yes, even though Earth is not round. Maybe "no problems with standard
headers" is just as correct as "Earth is round"? Works fine most of
the time, but not always.
Equally you have
the right to tell me that I am wrong. However, that is not what is
important here. What is important is what is true and what isn't, if you
don't think that then I think a technical group is the wrong place for you.
I think it's important not to make conclusions from absence of evidence
in technical groups. It's not a court. Exactly.
>>>But even if I wrote totally illegal code which worked fine, it'd be stupid if some unrelated library broke it. It would be totally fine as far as the standard is concerned, of course, UB and all that, so what?
For the record, I am not saying I am writing that evil code, nor am I advocating writing it. (I know, it can't help, you'll think I ask standard for something, moreover you will think I ask you for something, and so on)
You are advocating that there are good reasons to write stupidly broken code when writing a library,
Am I?
That's how it seemed.
Quote it. Please quote where I advocated using long instead of
size_t? I did try to make up some possible reasons for that,
and you simply said "no problems may exist with standard headers",
and I didn't agree with *this* claim. I advocated using long instead
of size_t?
>>everyone else is saying you are wrong. If you want to convince anyone that you are correct, or even that you have a valid if mistaken point of view, then *you* have to provide some concrete example, not hand waving and saying you know this library that does it and you are sure that it is because of broken headers and they have a good reason.
...
>>Second, if you define reserved identifiers >>like _GNU_SOURCE you invoke undefined behavior. You may *want* >>the undefined behavior, >> >See above, SYNOPSIS section. > As I said, you may want the undefined behavior.
I may want the well-defined behavior which left undefined by the standard. If the use of _GNU_SOURCE is documented by implementation, I may use it. But it's not the point of course.
That's one of those "personal matters" you refer to, but not a problem for C.
Who said it's a problem for C. Again, you are saying it like I am claiming standard owes me something, standard is completely wrong, and I invoke UB every day twice a day. No, I am saying that library developers may have an attitude of "user knows better what he's doing".
You are saying that the writer of a third party library has to do something everyone else considers stupid to prevent it being broken when you do something legal on a specific implementation. I say this is complete rubbish and the writer of the third party library should use the standard mechanisms provided. Either proved *real* *verifiable* evidence of your claim that there are good reasons or accept that the writers of that library have done the wrong thing.
Still, I can't do either. I can't accept something has done a wrong thing simply because I don't know the reason he did it.
Another good reason for providing what you believe are example. Then
people can explain why it was wrong or be convinced that there actually
is a good reason under some situation.
Interesting. Care to explain how I can provide an example of something
which I don't know whether it exists or not? I did say, like ten
times I *don't* know if there is a good reason. You can't get it,
can you? You seem to think either I say "yes" or "no", and "don't know"
qualifies as "yes". While your "don't know" implies "no". Oh well.
If you can it's your right. Of course, your opinion is backed up by opinions of other three people in this newsgroup, of yeah, collective wisdom.
Just tell, why does gnulib exist, why does it have so many wrappers for so many *standard* things? Because people working on it are stupid?
It exists to aid porting GNU, part of which *is* an implementation.
There are specific reasons why it still supports pre-C89 implementations
(actually, it is only the library they support as pre-C89). An
implementation no having been upgraded to C89 is not broken as such,
just old (or, rather, ancient), but supporting it requires wrapping
various standard library functions and dealing with not having standard
headers, or them not having been upgraded to match the C89 standard.
So it is *not* an example of working around broken implementations,
It is, if you think of C99 for a minute. stdbool.h and all that. But not
only that of course.
only
an example of comparability with ancient systems, and they are slowly
moving the goal posts forward.
It also wraps some functions to provide consistent behaviour where the
standard does not require it, for example wrapping malloc so that their
wrapped version when passed a size of 0 will try to allocate a byte and
so return a non-NULL value if possible.
Or fixes some broken string functions for the case when they are
broken in the implementation. You sure it does not work around any
bugs in implementations?
The documentation for gnulib also talks about the fact that it *can*
freely include the standard headers that are available in the oldest
implementation that is supports, so it is definitely *not* an example of
dealing with not being able to include the headers because they are too
broken.
Of course it's not, since gnulib is intended to be a complement to
any-C-library.
Keith Thompson wrote, On 16/03/07 23:33:
Flash Gordon <sp**@flash-gordon.me.ukwrites:
[...]
>Suggesting that they are avoiding the standard headers because they think some implementation has headers broken enough that they have to be avoided does suggest they are incompetent. However, elsewhere you have admitted that it is glibc and looking at the headers in some of them they *do* include stdef.h and stdio.h, so that obviously is *not* the reason.
<OT>
I think he said he's talking about glib, not glibc. glib and glibc
are two different things. glibc is the GNU implementation of the
standard C library. glib is "the low-level core library that forms
the basis of GTK+ and GNOME".
</OT>
I know that, I intended to type glib, my saying glibc was a trypo. glib
*does* include stdef.h, stdio.h and string.h (maybe others) from within
its headers.
--
Flash Gordon.
Yevgen Muntyan wrote, On 16/03/07 22:46:
Flash Gordon wrote:
>Yevgen Muntyan wrote, On 16/03/07 18:49:
>>Flash Gordon wrote: Yevgen Muntyan wrote, On 16/03/07 15:26: Flash Gordon wrote: >Yevgen Muntyan wrote, On 16/03/07 06:22: [snip] >>Dear Mr Heathfield, I do understand that saying in public you're not >>telling the truth is a bad offense. But when you're making totally >>ridiculous statements to justify your rudeness, I simply can't >>resist. >> >The last few posts in this thread by Richard and Eric do not seem >to be making ridiculous statements to me, only your posts seem to >be doing that. > Um, Mr Richard didn't quote me calling him a liar, did he? It wasn't about last few posts in this thread. Or do you mean Mr Heathfield is liar? Then, I didn't mean Eric words. I said "Mr Heathfield". What I said to Mr Richard has nothing to do with what I said to Eric Sosman.
I've never noticed either Richard Heathfield or Eric lying. I've seen them make mistakes, and I've certainly disagreed with Richard in the past (I don't keep score, but he has probably been right more often than me). However the way you have been attacking in this thread I can certainly see how what you've said can be interpreted as implying they are lying, in particular what you say above about Eric's comment.
Um, I am attacking, huh? Okay.
Saying something like, | Perhaps. I do understand that you have to earn right to be an asshole, | like Mr Heathfield has.
Certainly sounds like attacking to me.
This indeed does. I didn't understand you mean "attacking Mr.
Heathfield". Well, he came accusing me of calling him a liar, and
did not present any evidence of that. Ask him when I called him a
liar. Maybe you'll understand why I feel this way about him. Or
perhaps not. Or perhaps you'll be presented an evidence of him being
an asshole.
>Reviewing the thread, it looks like there are only a couple of instances of such things, so it might in part be you catching me on the wrong day or me finding you irritating for whatever reason.
>>>>>>Hm, somehow I don't believe you're most offended by me calling you >>a liar. For some reasons I think the worst thing is disagreement >>with you even after you present all your killer >>100%-correct-and-ignore-everything-else arguments. Did I just >>call you a >>liar again? >>Sorry about that, I do understand I will be hurt by this more >>than you. >> >Whether Richard and Eric feel offended or hurt does not change >whether it is an offensive thing to say. > So it's fine for Eric to insult other people by calling them incompetent, but it was so bad from me to say an offensive thing?
The evidence you present suggests that they are incompetent.
Bullshit.
Suggesting that they are avoiding the standard headers because they think some implementation has headers broken enough that they have to be avoided does suggest they are incompetent.
I did *not* say glib avoids using standard headers. It does not, in
fact. It does avoid string.h,
It does not. At least, not in the version installed on this machine.
markg@brenda:/usr/include/glib-2.0/gobject$ grep string.h *
gobjectnotifyqueue.c:#include <string.h/* memset */
but it doesn't avoid stddef.h. If you
think otherwise, please quote where I said glib uses unsigned long
instead of size_t because of headers thing.
Glib uses unsigned long there because of other reasons, which I
suspect are really "historic reasons". You and Eric easily jump
into "glib developers are incompetent". This is what I call bullshit,
or, politely, groundless, not honest and hostile.
You kept going on about knowing a library that did not use use size_t.
You also kept going on about how one reason for avoiding it could be to
avoid broken standard headers. If the two are unrelated then fine I
misread you.
However, there is still no reason to avoid the use of standard headers.
Some of the things in glib suggest trying to deal with pre-ANSI C, for
example defining NULL if it is not defined. Either that or it shows a
stupid (in my opinion) lack of trust in the standard libraries. The same
applies to the provision of an equivalent of the standard offsetof macro.
There is also invasion of the implementations name space with struct
_GSource etc.
So yes, there is certainly some grounds to say that the author(s) do not
know C properly.
Oh, and one comment I found particularly amusing. 'These are useful
because a "gint8" can be adjusted to be 1 byte (8 bits) on all
platforms.' Ignoring the terminology problem, if char is not 8 bits you
are stuffed in terms of finding an 8 bit type!
--
Flash Gordon
Flash Gordon wrote:
Yevgen Muntyan wrote, On 16/03/07 22:46:
>Flash Gordon wrote:
>>Yevgen Muntyan wrote, On 16/03/07 18:49: Flash Gordon wrote: Yevgen Muntyan wrote, On 16/03/07 15:26: >Flash Gordon wrote: >>Yevgen Muntyan wrote, On 16/03/07 06:22:
[snip]
>>>>>>>Hm, somehow I don't believe you're most offended by me calling you >>>a liar. For some reasons I think the worst thing is disagreement >>>with you even after you present all your killer >>>100%-correct-and-ignore-everything-else arguments. Did I just >>>call you a >>>liar again? >>>Sorry about that, I do understand I will be hurt by this more >>>than you. >>> >>Whether Richard and Eric feel offended or hurt does not change >>whether it is an offensive thing to say. >> >So it's fine for Eric to insult other people by calling them >incompetent, but it was so bad from me to say an offensive thing? > The evidence you present suggests that they are incompetent.
Bullshit.
Suggesting that they are avoiding the standard headers because they think some implementation has headers broken enough that they have to be avoided does suggest they are incompetent.
I did *not* say glib avoids using standard headers. It does not, in fact. It does avoid string.h,
It does not. At least, not in the version installed on this machine.
markg@brenda:/usr/include/glib-2.0/gobject$ grep string.h *
gobjectnotifyqueue.c:#include <string.h/* memset */
Um, so you did not understand I was talking about standard headers
in *headers*? If you really thought I was talking about library
sources, I apologize, and I must admit all I said seemed like
hundred times more stupid than I thought it did. Of course I meant
headers. Why do you think I was talking about that _GNU_SOURCE thing?
Because some glib source file is using it? Just to be clear,
#include <glib.h>
won't make declaration of strlen() visible. But size_t will be
defined.
but it doesn't avoid stddef.h. If you think otherwise, please quote where I said glib uses unsigned long instead of size_t because of headers thing. Glib uses unsigned long there because of other reasons, which I suspect are really "historic reasons". You and Eric easily jump into "glib developers are incompetent". This is what I call bullshit, or, politely, groundless, not honest and hostile.
You kept going on about knowing a library that did not use use size_t.
You also kept going on about how one reason for avoiding it could be to
avoid broken standard headers. If the two are unrelated then fine I
misread you.
However, there is still no reason to avoid the use of standard headers.
Some of the things in glib suggest trying to deal with pre-ANSI C, for
example defining NULL if it is not defined. Either that or it shows a
stupid (in my opinion) lack of trust in the standard libraries. The same
applies to the provision of an equivalent of the standard offsetof macro.
There is also invasion of the implementations name space with struct
_GSource etc.
So yes, there is certainly some grounds to say that the author(s) do not
know C properly.
Yeah, sure. Especially the last thing, about underscore-prefixed
identifiers. "Some grounds", huh? Indeed, some grounds. Now can
you say it in plain text, "glib developers are incompetent"?
Mumbling "some ground" surely helps not to lose face and still
make yourself right. Please make the claim you seem to be defending.
Oh, and one comment I found particularly amusing. 'These are useful
because a "gint8" can be adjusted to be 1 byte (8 bits) on all
platforms.' Ignoring the terminology problem, if char is not 8 bits you
are stuffed in terms of finding an 8 bit type!
You surely know that char is not signed char, I have no doubts about
that. You think these folks use "gint" because they think int may not
be available? However bad wording is (can't talk about it, it's not
my language), it means that gint8 plays the role of int8_t, but
in human-understandable language and without mentioning platforms
where char is not 8 bit (and the library won't work).
Yevgen This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: rayw |
last post by:
I used to believe that size_t was something to do with integral types, and
the std.
Something along the lines of ..
a char is 8 bits,
a int >= a char
a long >= int
|
by: bwaichu |
last post by:
To avoid padding in structures, where is the best place to put size_t
variables?
According the faq question 2.12 (http://c-faq.com/struct/padding.html),
it says:
"If you're worried about...
|
by: jacob navia |
last post by:
Rcently I posted code in this group, to help a user
that asked to know how he could find out the size of
a block allocated with malloc.
As always when I post something, the same group
of people...
|
by: subramanian100in |
last post by:
Consider the following program
#include <limits.h>
#include <stddef.h>
int main(void)
{
size_t size;
size_t bytes = sizeof(size_t);
|
by: Paulo Matos |
last post by:
Hello,
Is it safe to assume a size_t is an unsigned long? (is it forced by
the standard?)
Thank you,
Paulo Matos
|
by: Bob Cassel |
last post by:
I have the idea that ptr_diff_t had to be the same size as size_t from
Plauger's "The Standard C Library," where he states "... It is always
the signed type that has the same number of bits as the4...
|
by: lubomir dobsik |
last post by:
hi, i have seen an interesting thing:
#if sizeof((char*)0 - (char*)0) == sizeof(unsigned int)
typedef unsigned int size_t;
#elif sizeof((char*)0 - (char*)0) == sizeof(unsigned long)
typedef...
|
by: Tubular Technician |
last post by:
Hello, World!
Reading this group for some time I came to the conclusion that
people here are split into several fractions regarding size_t,
including, but not limited to,
* size_t is the...
|
by: jacek.dziedzic |
last post by:
Hi!
On a machine where size_t is 64-bit, unsigned long is 32-bit, how
does one construct a size_t literal that says 2^32? Typing in
size_t x = 4294967296UL;
complains about the value being...
|
by: lllomh |
last post by:
Define the method first
this.state = {
buttonBackgroundColor: 'green',
isBlinking: false, // A new status is added to identify whether the button is blinking or not
}
autoStart=()=>{
|
by: Mushico |
last post by:
How to calculate date of retirement from date of birth
|
by: DJRhino |
last post by:
Was curious if anyone else was having this same issue or not....
I was just Up/Down graded to windows 11 and now my access combo boxes are not acting right. With win 10 I could start typing...
|
by: giovanniandrean |
last post by:
The energy model is structured as follows and uses excel sheets to give input data:
1-Utility.py contains all the functions needed to calculate the variables and other minor things (mentions...
|
by: NeoPa |
last post by:
Introduction
For this article I'll be using a very simple database which has Form (clsForm) & Report (clsReport) classes that simply handle making the calling Form invisible until the Form, or all...
|
by: Teri B |
last post by:
Hi, I have created a sub-form Roles. In my course form the user selects the roles assigned to the course.
0ne-to-many. One course many roles.
Then I created a report based on the Course form and...
|
by: nia12 |
last post by:
Hi there,
I am very new to Access so apologies if any of this is obvious/not clear.
I am creating a data collection tool for health care employees to complete. It consists of a number of...
|
by: NeoPa |
last post by:
Introduction
For this article I'll be focusing on the Report (clsReport) class. This simply handles making the calling Form invisible until all of the Reports opened by it have been closed, when it...
|
by: isladogs |
last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM).
In this month's session, Mike...
| | |