Re: C89, size_t, and long
- From: Yevgen Muntyan <muntyan.removethis@xxxxxxxx>
- Date: Fri, 16 Mar 2007 16:12:46 GMT
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.h> and 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 providea 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 itfor 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 thebusiness 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
.
- Follow-Ups:
- Re: C89, size_t, and long
- From: Flash Gordon
- Re: C89, size_t, and long
- From: CBFalconer
- Re: C89, size_t, and long
- References:
- C89, size_t, and long
- From: Yevgen Muntyan
- Re: C89, size_t, and long
- From: Eric Sosman
- Re: C89, size_t, and long
- From: Yevgen Muntyan
- Re: C89, size_t, and long
- From: Eric Sosman
- Re: C89, size_t, and long
- From: Yevgen Muntyan
- Re: C89, size_t, and long
- From: Eric Sosman
- Re: C89, size_t, and long
- From: Yevgen Muntyan
- Re: C89, size_t, and long
- From: Richard Bos
- Re: C89, size_t, and long
- From: Yevgen Muntyan
- Re: C89, size_t, and long
- From: Richard Bos
- Re: C89, size_t, and long
- From: Yevgen Muntyan
- Re: C89, size_t, and long
- From: Eric Sosman
- Re: C89, size_t, and long
- From: Yevgen Muntyan
- Re: C89, size_t, and long
- From: Eric Sosman
- Re: C89, size_t, and long
- From: Yevgen Muntyan
- Re: C89, size_t, and long
- From: Flash Gordon
- C89, size_t, and long
- Prev by Date: Re: Simple but interesting issue
- Next by Date: Re: K&R 5-1
- Previous by thread: Re: C89, size_t, and long
- Next by thread: Re: C89, size_t, and long
- Index(es):
Relevant Pages
|