Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:[...]
Richard Harnden <richard.harnden@gmail.invalid> writes:
On 22/05/2025 23:32, Keith Thompson wrote:
In one of your library's headers:
extern const char ESCAPE;
In the corresponding *.c file:
const char ESCAPE = ('z' - 'a' == 25 ? '\x1b' : '\x27');
Change the name if you prefer.
Wouldn't that be a reserved identifier?
Yes, it would. Good catch.
(Identifiers starting with E followed by either a digit or an uppercase
letter are reserved; they could be defined as macros in <errno.h>.)
They are reserved only as macros, and only if <errno.h> has
been #include'd.
For this particular use, it's easy to make the definition work,
simply by adding
#undef ESCAPE
before the declaration in the header file, and before the
definition in the source file (assuming of course that if
there are any #include <errno.h> they precede the #undef's).
Someone (Jean-Marc) wrote some "folder" routines which I like a lot.
You can see them here:
https://sourceforge.net/p/pdos/gitcode/ci/master/tree/hwzip/folder.c
And in essence, when you read from a directory, the only
thing you get is the filename. If it is actually a subdirectory,
then that is indicated with a "/" at the end of the filename.
[elaboration]
Any thoughts (besides "get a life!")?
On 23.05.2025 07:20, Keith Thompson wrote:
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
[...]
If you have created a separate library, advertise it so that it
gets used, and if people are widely happy to have that library
suggest it for inclusion. Then committees might pick it up (or
not).
Or it might *not* be included in the language standard because
there's no need to do so. If a library is popular, programmers
can just use it whether it's part of the standard library or not.
Plenty of popular libraries are not part of the C standard library --
and they don't need to be.
Yes, sure. - I thought this was what I wrote [with other words];
"might pick it up (or not)".
Honestly, I still don't understand Paul's fixation on the standards
track; i.e. beyond the good feeling one may have when contributing
something [potentially] useful. If it's a sophisticated library and
made available to the public that could be reward enough. (But who
am I to judge. To each his own.)
"Paul Edwards" <mutazilah@gmail.com> writes:
But neither of these are in C23. Nor were they in C90.
I want a slight variation to BOTH of those standards,
and for the next ISO standard - C30 or whatever -
to include that slight variation.
(I didn't previously state this, because I wasn't aware
of it, again)
I don't believe
that you personally will have any influence over any
future C standard. Your goals are too different from the goals of the committee and those of the vast majority of people who care about C.
In this case, the plan is that my "add-on library", is so
small, and so useful, and hopefully so popular, that it
gets standardized into a theoretical C30, as well as
existing C90 libraries - including but not limited to
PDPCLIB - updated to include this new feature, that,
in hindsight, should have existed even in K&R C.
In my opinion that will never happen.
I have no problem with whatever functionality you want to provide in
your PDPCLIB, and I'm willing to discuss some of it in technical terms.
It's just a library. It may or may not
depend on features of the C90 standard library.
No. It IS C90+.
I don't know what you mean by that. If you mean that your PDPCLIB
library IS "C90+", that's fine; both are your invented terms.
But it's an odd choice of terminology.
This is intended to be in the official ISO C standard for the next
1 million years.
That will not happen.
Actually influencing ISO is a separate exercise.
That will not happen either.
It probably won't involve coercion.
But coercion wouldn't be required if the C90+ committee comes
up with something reasonable.
That sounds like a threat. If it is, I suggest you stick it where the
sun don't shine. But as far as I know you have no ability to carry out
your threat, so it's more pathetically amusing that frightening.
And if I am one day elected president of the USA, at the
same time as Chancellor of Germany, and a few other
places, you may well find 90% of the planet using it (or
at least, having it on their system).
See above regarding "where the sun don't shine".
E.g. I can't drive an EBCDIC X3.64 terminal unless C90[...]
provides an ESC define.
That's what C90 is all about after all - making things as[...]
completely portable as possible.
That's convey. Not convince.
It never ever occurred to me that a US president would one
day [SNIP]
"Paul Edwards" <mutazilah@gmail.com> writes:
[...]
E.g. I can't drive an EBCDIC X3.64 terminal unless C90[...]
provides an ESC define.
Of course you can.
You can just use '\x27' in your code. It doesn't
have to be part of the language standard. If you have an application
that, for whatever reason, needs to drive both ASCII and EBCDIC
terminals, you can configure it by any means you like to use
'\x1b' or '\x27` (command-line argument, environment variable,
configuration file, reply from the terminal, whatever).
The idea that you can't do that without a constant defined in your
language standard is just silly.
That's what C90 is all about after all - making things as
completely portable as possible.
No, that's not what C90 was ever about. Very few C programs are
completely portable, because they don't need to be.
And if you want to talk
about coercing or bribing members of the C committee or any similar antisocial behaviors
"Paul Edwards" <mutazilah@gmail.com> writes:
[...]
It never ever occurred to me that a US president would one
day [SNIP]
I urge you to stick to the topic of this newsgroup. If you want
to talk about politics, don't do it here. And if you want to talk
about coercing or bribing members of the C committee or any similar >antisocial behaviors, keep it to yourself.
I can't stop you from posting here. I can ignore you.
On Fri, 23 May 2025 07:52:27 +1000, Paul Edwards wrote:
Moreover, what is the definition of 'character' in this context?
Something that fgetc() would be able to consume without blocking.
That wouldn't cope with Unicode. Anything that can't cope with Unicode
isn't going to be considered very useful nowadays.
"Lawrence D'Oliveiro" <ldo@nz.invalid> wrote in message news:100oicc$3ob15$3@dont-email.me...
On Fri, 23 May 2025 07:52:27 +1000, Paul Edwards wrote:
Moreover, what is the definition of 'character' in this context?
Something that fgetc() would be able to consume without blocking.
That wouldn't cope with Unicode. Anything that can't cope with Unicode
isn't going to be considered very useful nowadays.
"people nowadays" don't speak with one voice.
"Keith Thompson" <Keith.S.Thompson+u@gmail.com> wrote in message news:87a570jpe6.fsf@nosuchdomain.example.com...
You can just use '\x27' in your code. It doesn't
have to be part of the language standard. If you have an application
that, for whatever reason, needs to drive both ASCII and EBCDIC
terminals, you can configure it by any means you like to use
'\x1b' or '\x27` (command-line argument, environment variable,
configuration file, reply from the terminal, whatever).
Yes, I agree those are standards-conforming alternatives.
But not what I want. For reasons which are difficult for me
to elaborate - "aesthetic", or "self-contained" may or may
not be apt words - I want to include the ESCAPE in the
C code, just like the "hello, world\n" bit.
The C90 committee didn't force me to accept "\n" from a
config file, so that I could have CRLF on MSDOS.
[...]
"Janis Papanagnou" <janis_papanagnou+ng@hotmail.com> wrote in message news:100p1u4$3um4p$1@dont-email.me...
On 23.05.2025 07:20, Keith Thompson wrote:
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
[...]
If you have created a separate library, advertise it so that it
gets used, and if people are widely happy to have that library
suggest it for inclusion. Then committees might pick it up (or
not).
Or it might *not* be included in the language standard because
there's no need to do so. If a library is popular, programmers
can just use it whether it's part of the standard library or not.
Plenty of popular libraries are not part of the C standard library --
and they don't need to be.
Yes, sure. - I thought this was what I wrote [with other words];
"might pick it up (or not)".
Honestly, I still don't understand Paul's fixation on the standards
track; i.e. beyond the good feeling one may have when contributing
something [potentially] useful. If it's a sophisticated library and
made available to the public that could be reward enough. (But who
am I to judge. To each his own.)
(sorry for the delay in replying)
[snip many lines]
On 26.05.2025 00:40, Paul Edwards wrote:
"Keith Thompson" <Keith.S.Thompson+u@gmail.com> wrote in message news:87a570jpe6.fsf@nosuchdomain.example.com...
You can just use '\x27' in your code. It doesn't
have to be part of the language standard. If you have an application
that, for whatever reason, needs to drive both ASCII and EBCDIC
terminals, you can configure it by any means you like to use
'\x1b' or '\x27` (command-line argument, environment variable,
configuration file, reply from the terminal, whatever).
Yes, I agree those are standards-conforming alternatives.
But not what I want. For reasons which are difficult for me
to elaborate - "aesthetic", or "self-contained" may or may
not be apt words - I want to include the ESCAPE in the
C code, just like the "hello, world\n" bit.
Doesn't '\e' work for you?
The C90 committee didn't force me to accept "\n" from a
config file, so that I could have CRLF on MSDOS.
If what you want as "escape" is a semantical name also on your
EBCDIC systems then I'd expect a compiler to use the correct
encoding for '\e'.
(If OTOH that "escape" isn't a general semantical term then it
wouldn't be reflected by the compiler; you certainly cannot
expect it be defined through a _configuration_ file.)
On Mon, 26 May 2025 09:48:46 +1000, Paul Edwards wrote:
"Lawrence D'Oliveiro" <ldo@nz.invalid> wrote in message news:100oicc$3ob15$3@dont-email.me...
On Fri, 23 May 2025 07:52:27 +1000, Paul Edwards wrote:
Moreover, what is the definition of 'character' in this context?
Something that fgetc() would be able to consume without blocking.
That wouldn't cope with Unicode. Anything that can't cope with Unicode
isn't going to be considered very useful nowadays.
"people nowadays" don't speak with one voice.
Nor with one language. Which is why we have Unicode.
The idea that you can't do that without a constant defined in your
language standard is just silly.
It may be silly from your perspective, but for me it is crucial.
On 26.05.2025 00:40, Paul Edwards wrote:....
But not what I want. For reasons which are difficult for me
to elaborate - "aesthetic", or "self-contained" may or may
not be apt words - I want to include the ESCAPE in the
C code, just like the "hello, world\n" bit.
Doesn't '\e' work for you?
char * str = "\e";
puts (str);
printf ("\e\n");
putchar ('\e');
putchar ('\n');
Works for me. - Is that non-standard?
On 5/25/25 21:29, Janis Papanagnou wrote:
On 26.05.2025 00:40, Paul Edwards wrote:...
But not what I want. For reasons which are difficult for me
to elaborate - "aesthetic", or "self-contained" may or may
not be apt words - I want to include the ESCAPE in the
C code, just like the "hello, world\n" bit.
Doesn't '\e' work for you?
char * str = "\e";
puts (str);
printf ("\e\n");
putchar ('\e');
putchar ('\n');
Works for me. - Is that non-standard?
Yes. It's a common extension.
C99 is just as stable as C90, and has been for well over a
decade.
C11 is just as stable as C90, and has been for just slightly
less than a decade.
Groovy hepcat Tim Rentsch was jivin' in comp.lang.c on Fri, 23 May 2025
10:43 pm. It's a cool scene! Dig it.
C99 is just as stable as C90, and has been for well over a
decade.
Methinks Tim is having trouble with his arithmetic. Either that or he doesn't know what year it is now. :)
C99 was ratified in 1999, over two and a half decades ago.
C11 is just as stable as C90, and has been for just slightly
less than a decade.
And C11 was ratified in 2011, no? That was almost a decade and a half
ago.
On 26/05/2025 07:19, Peter 'Shaggy' Haywood wrote:
Groovy hepcat Tim Rentsch was jivin' in comp.lang.c on Fri, 23 May
2025 10:43 pm. It's a cool scene! Dig it.
C99 is just as stable as C90, and has been for well over a
decade.
Methinks Tim is having trouble with his arithmetic. Either that
or he doesn't know what year it is now. :)
C99 was ratified in 1999, over two and a half decades ago.
C11 is just as stable as C90, and has been for just slightly
less than a decade.
And C11 was ratified in 2011, no? That was almost a decade and a
half ago.
Tim was, I believe, taking into account the time it took for common implementations of C compilers and libraries to have complete and
generally bug-free support for the standards, and for these
implementations to become common. C99 was published in 1999, but it
took quite a while before most people programming in C could happily
use C99 without worrying about the tool support being "experimental"
or not as mature as C90 support.
On Tue, 27 May 2025 16:23:22 +0200
David Brown <david.brown@hesbynett.no> wrote:
On 26/05/2025 07:19, Peter 'Shaggy' Haywood wrote:
Groovy hepcat Tim Rentsch was jivin' in comp.lang.c on Fri, 23 May
2025 10:43 pm. It's a cool scene! Dig it.
C99 is just as stable as C90, and has been for well over a
decade.
Methinks Tim is having trouble with his arithmetic. Either that
or he doesn't know what year it is now. :)
C99 was ratified in 1999, over two and a half decades ago.
C11 is just as stable as C90, and has been for just slightly
less than a decade.
And C11 was ratified in 2011, no? That was almost a decade and a
half ago.
Tim was, I believe, taking into account the time it took for common
implementations of C compilers and libraries to have complete and
generally bug-free support for the standards, and for these
implementations to become common. C99 was published in 1999, but it
took quite a while before most people programming in C could happily
use C99 without worrying about the tool support being "experimental"
or not as mature as C90 support.
I believe that your belief is wrong.
It is much more likely that Tim took into account defect reports.
Here is the list of C11 defect reports with the last dated 2016: https://open-std.org/jtc1/sc22/wg14/www/docs/summary.htm
I did not find similar list for C99. However believing Tim I would guess
that the last change in C99 document was made ~15 years ago.
On Tue, 27 May 2025 16:23:22 +0200
David Brown <david.brown@hesbynett.no> wrote:
On 26/05/2025 07:19, Peter 'Shaggy' Haywood wrote:
Groovy hepcat Tim Rentsch was jivin' in comp.lang.c on Fri, 23 May
2025 10:43 pm. It's a cool scene! Dig it.
C99 is just as stable as C90, and has been for well over a
decade.
Methinks Tim is having trouble with his arithmetic. Either that
or he doesn't know what year it is now. :)
C99 was ratified in 1999, over two and a half decades ago.
C11 is just as stable as C90, and has been for just slightly
less than a decade.
And C11 was ratified in 2011, no? That was almost a decade and a
half ago.
Tim was, I believe, taking into account the time it took for common
implementations of C compilers and libraries to have complete and
generally bug-free support for the standards, and for these
implementations to become common. C99 was published in 1999, but it
took quite a while before most people programming in C could happily
use C99 without worrying about the tool support being "experimental"
or not as mature as C90 support.
I believe that your belief is wrong.
It is much more likely that Tim took into account defect reports.
Here is the list of C11 defect reports with the last dated 2016: https://open-std.org/jtc1/sc22/wg14/www/docs/summary.htm
I did not find similar list for C99. However believing Tim I would guess that the last change in C99 document was made ~15 years ago.
Groovy hepcat Tim Rentsch was jivin' in comp.lang.c on Fri, 23 May 2025
10:43 pm. It's a cool scene! Dig it.
C99 is just as stable as C90, and has been for well over a
decade.
Methinks Tim is having trouble with his arithmetic. Either that or he doesn't know what year it is now. :)
C99 was ratified in 1999, over two and a half decades ago.
C11 is just as stable as C90, and has been for just slightly
less than a decade.
And C11 was ratified in 2011, no? That was almost a decade and a half
ago.
On 24/05/2025 06:32, Tim Rentsch wrote:
Richard Heathfield <rjh@cpax.org.uk> writes:
On 23/05/2025 13:43, Tim Rentsch wrote:
Richard Heathfield <rjh@cpax.org.uk> writes:
On 20/05/2025 10:18, Keith Thompson wrote:
C90 will never be extended.
And for that reason it will always be valuable. Stability
has a value all its own.
C99 is just as stable as C90, and has been for well over a
decade.
Sure, but it's a different stable.
If it were the same stable, it would be C90.
C99 isn't C90, therefore it isn't the same stable.
If you tell me C99 is a rock, I will not doubt you. But the C90
rock it most certainly isn't.
Now you're being silly.
No, sir. If you want to play that game, you can play it with
yourself. I know that you are perfectly capable of polite
conversation, so I see no reason to endure the opposite.
Michael S <already5chosen@yahoo.com> writes:
On Tue, 27 May 2025 16:23:22 +0200
David Brown <david.brown@hesbynett.no> wrote:
On 26/05/2025 07:19, Peter 'Shaggy' Haywood wrote:
Groovy hepcat Tim Rentsch was jivin' in comp.lang.c on Fri, 23 May
2025 10:43 pm. It's a cool scene! Dig it.
C99 is just as stable as C90, and has been for well over a
decade.
Methinks Tim is having trouble with his arithmetic. Either
that or he doesn't know what year it is now. :)
C99 was ratified in 1999, over two and a half decades ago.
C11 is just as stable as C90, and has been for just slightly
less than a decade.
And C11 was ratified in 2011, no? That was almost a decade
and a half ago.
Tim was, I believe, taking into account the time it took for common
implementations of C compilers and libraries to have complete and
generally bug-free support for the standards, and for these
implementations to become common. C99 was published in 1999, but
it took quite a while before most people programming in C could
happily use C99 without worrying about the tool support being
"experimental" or not as mature as C90 support.
I believe that your belief is wrong.
It is much more likely that Tim took into account defect reports.
Here is the list of C11 defect reports with the last dated 2016: https://open-std.org/jtc1/sc22/wg14/www/docs/summary.htm
I did not find similar list for C99. However believing Tim I would
guess that the last change in C99 document was made ~15 years ago.
You are partly right. Besides defect reports, there are TCs. And
there is always the possibility of future TCs, future defect
reports, or future changes for any ISO C standard while it is
still current.
To be as stable as C90, a C standard would need to be immune to
the possibility of such future changes.
I take C99 to have reached this level of stability in 2011, when
it was superseded by C11. I take C11 to have reached this level
of stability in 2017, when it was superseded by C17.
Richard Heathfield <rjh@cpax.org.uk> writes:
On 24/05/2025 06:32, Tim Rentsch wrote:
Richard Heathfield <rjh@cpax.org.uk> writes:
On 23/05/2025 13:43, Tim Rentsch wrote:
Richard Heathfield <rjh@cpax.org.uk> writes:
On 20/05/2025 10:18, Keith Thompson wrote:
C90 will never be extended.
And for that reason it will always be valuable. Stability
has a value all its own.
C99 is just as stable as C90, and has been for well over a
decade.
Sure, but it's a different stable.
If it were the same stable, it would be C90.
C99 isn't C90, therefore it isn't the same stable.
If you tell me C99 is a rock, I will not doubt you. But the C90
rock it most certainly isn't.
Now you're being silly.
No, sir. If you want to play that game, you can play it with
yourself. I know that you are perfectly capable of polite
conversation, so I see no reason to endure the opposite.
I don't think I'm being impolite.
Got it. Stability occurs when the standards is fenced from changes by presence of the next edition.
"Lawrence D'Oliveiro" <ldo@nz.invalid> wrote in message news:100j8t8$2g75r$5@dont-email.me...
On Wed, 21 May 2025 07:41:12 +1000, Paul Edwards wrote:
Basically the software industry is a joke. The advances have all been
done by hardware engineers.
Didn't they use software to manage that?
Yes - as the guy (Jeff) said - software written by lunatics/artists.
"Lawrence D'Oliveiro" <ldo@nz.invalid> wrote in message news:1010bqn$1l25r$1@dont-email.me...
On Mon, 26 May 2025 09:48:46 +1000, Paul Edwards wrote:
"people nowadays" don't speak with one voice.
Nor with one language. Which is why we have Unicode.
Which is one solution to the problem.
Just not a solution I agree with.
I prefer VISCII-like, possibly requiring a 9-bit char, and invalidating
all applications with POSIX assumptions.
And who cares about future instability if C90 remains just as stable as
ever it was?
On 2025-05-28, Michael S <already5chosen@yahoo.com> wrote:
Got it. Stability occurs when the standards is fenced from changes by
presence of the next edition.
Each technical corrigendum effectively yields a new edition.
The previous standard without that corrigendum is forever stable,
as any immutable object.
On Fri, 23 May 2025 23:13:20 +0100, Richard Heathfield wrote:
And who cares about future instability if C90 remains just as stable as
ever it was?
Even with the problems with const?
char *strstr(const char *haystack, const char *needle);
Dennis Ritchie pointed out the trouble with that.
On 29/05/2025 08:27, Lawrence D'Oliveiro wrote:
On Fri, 23 May 2025 23:13:20 +0100, Richard Heathfield wrote:
And who cares about future instability if C90 remains just as stable
as ever it was?
Even with the problems with const?
char *strstr(const char *haystack, const char *needle);
Dennis Ritchie pointed out the trouble with that.
Is C90 perfect? No, of course not.
On Thu, 29 May 2025 09:39:51 +0100, Richard Heathfield wrote:....
Is C90 perfect? No, of course not.
Is there some value in that particular state of imperfection? Like the Amish, whose concept of the ideal level of technology is the one that was
in effect at the time they were founded? And who have remained stuck at
that point in time ever since?
On Thu, 29 May 2025 09:39:51 +0100, Richard Heathfield wrote:
On 29/05/2025 08:27, Lawrence D'Oliveiro wrote:
On Fri, 23 May 2025 23:13:20 +0100, Richard Heathfield wrote:
And who cares about future instability if C90 remains just as stable
as ever it was?
Even with the problems with const?
char *strstr(const char *haystack, const char *needle);
Dennis Ritchie pointed out the trouble with that.
Is C90 perfect? No, of course not.
Is there some value in that particular state of imperfection?
Like the
Amish, whose concept of the ideal level of technology is the one that was
in effect at the time they were founded? And who have remained stuck at
that point in time ever since?
On 5/29/25 05:37, Lawrence D'Oliveiro wrote:
On Thu, 29 May 2025 09:39:51 +0100, Richard Heathfield wrote:...
Is C90 perfect? No, of course not.
Is there some value in that particular state of imperfection? Like the
Amish, whose concept of the ideal level of technology is the one that was
in effect at the time they were founded? And who have remained stuck at
that point in time ever since?
That's not actually the case. The Amish have slowly adopted more
advanced levels of technology as the people around them have adopted
farm more advanced ones. The important thing, from their point of view,
it not a particular level of technology, but to maintain a clear
distinction between them and the non-Amish.
Which means that they are more adaptable than Richard is.
On Wed, 21 May 2025 19:23:45 +1000, Paul Edwards wrote:
"Lawrence D'Oliveiro" <ldo@nz.invalid> wrote in message
news:100j8t8$2g75r$5@dont-email.me...
On Wed, 21 May 2025 07:41:12 +1000, Paul Edwards wrote:
Basically the software industry is a joke. The advances have all been
done by hardware engineers.
Didn't they use software to manage that?
Yes - as the guy (Jeff) said - software written by lunatics/artists.
Was RCU invented by the hardware guys, or the software guys?
On 29/05/2025 11:11, James Kuyper wrote:
On 5/29/25 05:37, Lawrence D'Oliveiro wrote:
On Thu, 29 May 2025 09:39:51 +0100, Richard Heathfield wrote:...
Is C90 perfect? No, of course not.
Is there some value in that particular state of imperfection? Like the
Amish, whose concept of the ideal level of technology is the one that was >>> in effect at the time they were founded? And who have remained stuck at
that point in time ever since?
That's not actually the case. The Amish have slowly adopted more
advanced levels of technology as the people around them have adopted
farm more advanced ones. The important thing, from their point of view,
it not a particular level of technology, but to maintain a clear
distinction between them and the non-Amish.
Which means that they are more adaptable than Richard is.
They use a lot of C++, do they?
Richard Heathfield <rjh@cpax.org.uk> writes:
On 29/05/2025 11:11, James Kuyper wrote:
On 5/29/25 05:37, Lawrence D'Oliveiro wrote:
On Thu, 29 May 2025 09:39:51 +0100, Richard Heathfield wrote:...
Is C90 perfect? No, of course not.
Is there some value in that particular state of imperfection? Like the >>>> Amish, whose concept of the ideal level of technology is the one that was >>>> in effect at the time they were founded? And who have remained stuck at >>>> that point in time ever since?
That's not actually the case. The Amish have slowly adopted more
advanced levels of technology as the people around them have adopted
farm more advanced ones. The important thing, from their point of view,
it not a particular level of technology, but to maintain a clear
distinction between them and the non-Amish.
Which means that they are more adaptable than Richard is.
They use a lot of C++, do they?
They do love power tools.
You can have new tools without breaking the old ones. We didn't
have to change BCPL to get B, or B to get C, or C to get D or C++.
This really is a very simple point, but perhaps a simple analogy
will help to clarify it. You don't throw out your 3/4" just
because you've bought a 19mm. There is room for both in the
toolbox, and why write 3/4" on your new spanner? It /isn't/ a
3/4" spanner even though it's very like it, so why pretend otherwise?
If you want to take down a tree in a hurry, a chainsaw is just
the job, but more delicate work requires more delicate tools.
On 5/29/25 08:38, Richard Heathfield wrote:
...
You can have new tools without breaking the old ones. We didn't
have to change BCPL to get B, or B to get C, or C to get D or C++.
This really is a very simple point, but perhaps a simple analogy
will help to clarify it. You don't throw out your 3/4" just
because you've bought a 19mm. There is room for both in the
toolbox, and why write 3/4" on your new spanner? It /isn't/ a
3/4" spanner even though it's very like it, so why pretend otherwise?
That's why C99 is called C99, to distinguish it from C90 (and similarly
for later versions).
On 2025-05-29, Richard Heathfield <rjh@cpax.org.uk> wrote:
If you want to take down a tree in a hurry, a chainsaw is just
the job, but more delicate work requires more delicate tools.
(I'm now searching YouTube for anyone in Asia who might be
carving jade amulets with a chainsaw ...)
On 29/05/2025 08:27, Lawrence D'Oliveiro wrote:
On Fri, 23 May 2025 23:13:20 +0100, Richard Heathfield wrote:
And who cares about future instability if C90 remains just as stable as
ever it was?
Even with the problems with const?
char *strstr(const char *haystack, const char *needle);
Dennis Ritchie pointed out the trouble with that.
Is C90 perfect? No, of course not. "C is quirky, flawed, and an enormous success."
Is there value in having a powerful, widely-available language that,
when you turn your back for a moment, stays *exactly* where you left it? Hell, yes.
On 29/05/2025 10:39, Richard Heathfield wrote:
On 29/05/2025 08:27, Lawrence D'Oliveiro wrote: =20=20
On Fri, 23 May 2025 23:13:20 +0100, Richard Heathfield wrote:=20
=20
And who cares about future instability if C90 remains just as
stable as ever it was? =20
Even with the problems with const?
=A0=A0=A0=A0 char *strstr(const char *haystack, const char *needle);
Dennis Ritchie pointed out the trouble with that. =20
Is C90 perfect? No, of course not. "C is quirky, flawed, and an
enormous success."
=20
Is there value in having a powerful, widely-available language
that, when you turn your back for a moment, stays *exactly* where
you left it? Hell, yes.
=20
That's one of the reasons I like C99 and C11, and look forward to
C23. Once implemented, they don't change either.
=20
I agree with all your are arguments on this, except for one - I can't=20 understand why you think C90 is different from later C standards in
this regard.
=20
On 29/05/2025 10:39, Richard Heathfield wrote:
On 29/05/2025 08:27, Lawrence D'Oliveiro wrote:
On Fri, 23 May 2025 23:13:20 +0100, Richard Heathfield wrote:
And who cares about future instability if C90 remains just as
stable as
ever it was?
Even with the problems with const?
char *strstr(const char *haystack, const char *needle);
Dennis Ritchie pointed out the trouble with that.
Is C90 perfect? No, of course not. "C is quirky, flawed, and an
enormous success."
Is there value in having a powerful, widely-available language
that, when you turn your back for a moment, stays *exactly*
where you left it? Hell, yes.
That's one of the reasons I like C99 and C11, and look forward to
C23. Once implemented, they don't change either.
I agree with all your are arguments on this,
except for one - I
can't understand why you think C90 is different from later C
standards in this regard.
On 29/05/2025 20:24, David Brown wrote:[...]
That's one of the reasons I like C99 and C11, and look forward to
C23. Once implemented, they don't change either.
I agree with all your are arguments on this,
So far so good. :-)
except for one - I can't understand why you think C90 is different
from later C standards in this regard.
I realise that my reply is going to sound glib, but I can't help that.
I *don't* think C90 is different. I think C90 is exactly the
same. It's the later standards that are different. Different from C90.
Richard Heathfield <rjh@cpax.org.uk> writes:
On 29/05/2025 20:24, David Brown wrote:[...]
That's one of the reasons I like C99 and C11, and look forward to
C23. Once implemented, they don't change either.
I agree with all your are arguments on this,
So far so good. :-)
except for one - I can't understand why you think C90 is different
from later C standards in this regard.
I realise that my reply is going to sound glib, but I can't help that.
I *don't* think C90 is different. I think C90 is exactly the
same. It's the later standards that are different. Different from C90.
I'd like to understand the point you're trying to make.
Being different is a transitive relationship. C90 is different
"from later C standards". You say that C90 is "exactly the same"
-- as what? As itself?
C99 is also exactly the same as itself.
If the difference is that you personally like C90 and dislike C99
and later editions, that's fine. De gustibus non est disputandem
(never argue with a guy named Gus).
On 29/05/2025 21:45, Keith Thompson wrote:
Richard Heathfield <rjh@cpax.org.uk> writes:
On 29/05/2025 20:24, David Brown wrote:[...]
That's one of the reasons I like C99 and C11, and look forward to
C23. Once implemented, they don't change either.
I agree with all your are arguments on this,
So far so good. :-)
except for one - I can't understand why you think C90 is different
from later C standards in this regard.
I realise that my reply is going to sound glib, but I can't help that.
I *don't* think C90 is different. I think C90 is exactly the
same. It's the later standards that are different. Different from C90.
I'd like to understand the point you're trying to make.
I'll do what I can to help out; I'm really not trying to be obscure.
Being different is a transitive relationship. C90 is different
"from later C standards". You say that C90 is "exactly the same"
-- as what? As itself?
Yes. And nothing else has that quality of being C90.
C99 is also exactly the same as itself.
Yes, but it's different from C99.
If the difference is that you personally like C90 and dislike C99
and later editions, that's fine. De gustibus non est disputandem
(never argue with a guy named Gus).
Look, Gus, if that's what you want to call yourself...well, okay,
I can't in all honesty deny that de gustibus is part of it, but
it's more to do with bit rot.
Software houses need C90 for the same reason the government needs
IBM 1311s (unless they've finished migrating off them now),
cassette players, WW2 crypto keys, and the boot passwords for
those early 1990s PCs lurking in the cellar.
I shudder to think how much C90 code is out there, but it has to
be /at least/ in the region of 10^9 LOC, much of it in the
military arena, medical applications, and particularly the world
of comms. Letting C90 compilers fall off the radar (e.g. by
society forgetting how to program in it) really could be a
stupendously bad idea, for all the reasons that people overlook
when they shrug and say `I expect it'll all turn out fine'.
On 29/05/2025 11:11, James Kuyper wrote:
On 5/29/25 05:37, Lawrence D'Oliveiro wrote:
On Thu, 29 May 2025 09:39:51 +0100, Richard Heathfield wrote:...
Is C90 perfect? No, of course not.
Is there some value in that particular state of imperfection? Like the
Amish, whose concept of the ideal level of technology is the one that
was
in effect at the time they were founded? And who have remained stuck at
that point in time ever since?
That's not actually the case. The Amish have slowly adopted more
advanced levels of technology as the people around them have adopted
farm more advanced ones. The important thing, from their point of view,
it not a particular level of technology, but to maintain a clear
distinction between them and the non-Amish.
Which means that they are more adaptable than Richard is.
They use a lot of C++, do they?
On 29/05/2025 16:08, Scott Lurndal wrote:
Richard Heathfield <rjh@cpax.org.uk> writes:
On 29/05/2025 11:11, James Kuyper wrote:
On 5/29/25 05:37, Lawrence D'Oliveiro wrote:
On Thu, 29 May 2025 09:39:51 +0100, Richard Heathfield wrote:...
Is C90 perfect? No, of course not.
Is there some value in that particular state of imperfection? Like the >>>>> Amish, whose concept of the ideal level of technology is the one
that was
in effect at the time they were founded? And who have remained
stuck at
that point in time ever since?
That's not actually the case. The Amish have slowly adopted more
advanced levels of technology as the people around them have adopted
farm more advanced ones. The important thing, from their point of view, >>>> it not a particular level of technology, but to maintain a clear
distinction between them and the non-Amish.
Which means that they are more adaptable than Richard is.
They use a lot of C++, do they?
They do love power tools.
:-)
If you want to take down a tree in a hurry, a chainsaw is just the job,
but more delicate work requires more delicate tools.
More to the point, if you have a million lines of legacy code all
written in C90, it's a bloody good idea to keep a C90 compiler around because maintenance.
Richard Heathfield <rjh@cpax.org.uk> writes:
On 29/05/2025 21:45, Keith Thompson wrote:
C99 is also exactly the same as itself.
Yes, but it's different from C99.
I shudder to think how much C90 code is out there, but it has to
be /at least/ in the region of 10^9 LOC, much of it in the
military arena, medical applications, and particularly the world
of comms. Letting C90 compilers fall off the radar (e.g. by
society forgetting how to program in it) really could be a
stupendously bad idea, for all the reasons that people overlook
when they shrug and say `I expect it'll all turn out fine'.
And all the existing C compilers in the entire planet support
the C90 dialect[*], if so instructed.
Where is the problem?
[*] Well, except perhap Bart's and various hobby compilers.
On 29/05/2025 21:45, Keith Thompson wrote:
Richard Heathfield <rjh@cpax.org.uk> writes:
On 29/05/2025 20:24, David Brown wrote:[...]
I'd like to understand the point you're trying to make.That's one of the reasons I like C99 and C11, and look forward to
C23. Once implemented, they don't change either.
I agree with all your are arguments on this,
So far so good. :-)
except for one - I can't understand why you think C90 is different
from later C standards in this regard.
I realise that my reply is going to sound glib, but I can't help that.
I *don't* think C90 is different. I think C90 is exactly the
same. It's the later standards that are different. Different from C90.
I'll do what I can to help out; I'm really not trying to be obscure.
Being different is a transitive relationship. C90 is different
"from later C standards". You say that C90 is "exactly the same"
-- as what? As itself?
Yes. And nothing else has that quality of being C90.
C99 is also exactly the same as itself.
Yes, but it's different from C99.
If the difference is that you personally like C90 and dislike C99
and later editions, that's fine. De gustibus non est disputandem
(never argue with a guy named Gus).
Look, Gus, if that's what you want to call yourself...well, okay, I
can't in all honesty deny that de gustibus is part of it, but it's
more to do with bit rot.
Software houses need C90 for the same reason the government needs IBM
1311s (unless they've finished migrating off them now), cassette
players, WW2 crypto keys, and the boot passwords for those early 1990s
PCs lurking in the cellar.
I shudder to think how much C90 code is out there, but it has to be
/at least/ in the region of 10^9 LOC, much of it in the military
arena, medical applications, and particularly the world of
comms. Letting C90 compilers fall off the radar (e.g. by society
forgetting how to program in it) really could be a stupendously bad
idea, for all the reasons that people overlook when they shrug and say
`I expect it'll all turn out fine'.
Richard Heathfield <rjh@cpax.org.uk> writes:
On 29/05/2025 21:45, Keith Thompson wrote:
Richard Heathfield <rjh@cpax.org.uk> writes:
On 29/05/2025 20:24, David Brown wrote:[...]
I'd like to understand the point you're trying to make.That's one of the reasons I like C99 and C11, and look forward to
C23. Once implemented, they don't change either.
I agree with all your are arguments on this,
So far so good. :-)
except for one - I can't understand why you think C90 is different
from later C standards in this regard.
I realise that my reply is going to sound glib, but I can't help that. >>>>
I *don't* think C90 is different. I think C90 is exactly the
same. It's the later standards that are different. Different from C90.
I'll do what I can to help out; I'm really not trying to be obscure.
Being different is a transitive relationship. C90 is different
"from later C standards". You say that C90 is "exactly the same"
-- as what? As itself?
Yes. And nothing else has that quality of being C90.
C99 is also exactly the same as itself.
Yes, but it's different from C99.
I hope that was a typo. If you really meant that C99 is different from
C99, I suggest that requires a bit more explanation.
Obviously C90, C99, and C11 are all different from each other.
You seem to be suggesting that C90 is special in some way that C99
and C11 are not.
If that's an accurate summary of your opinion,
can you explain it?
And if it isn't, just what are we talking about?
Software houses need C90 for the same reason the government needs
IBM 1311s (unless they've finished migrating off them now),
cassette players, WW2 crypto keys, and the boot passwords for
those early 1990s PCs lurking in the cellar.
I shudder to think how much C90 code is out there, but it has to
be /at least/ in the region of 10^9 LOC, much of it in the
military arena, medical applications, and particularly the world
of comms. Letting C90 compilers fall off the radar (e.g. by
society forgetting how to program in it) really could be a
stupendously bad idea, for all the reasons that people overlook
when they shrug and say `I expect it'll all turn out fine'.
This really is a very simple point, but perhaps a simple analogy
will help to clarify it. You don't throw out your 3/4" just
because you've bought a 19mm. There is room for both in the
toolbox, and why write 3/4" on your new spanner? It /isn't/ a
3/4" spanner even though it's very like it, so why pretend otherwise?
Concerning new code it makes sense to avoid constructs that
are made illegal in later standard, that is write to the
latter of later standard even if you use only constructs
available in C90.
I shudder to think how much C90 code is out there, but it has to be /at least/ in the region of 10^9 LOC, much of it in the military arena,
medical applications, and particularly the world of comms.
Richard Heathfield <rjh@cpax.org.uk> writes:
I shudder to think how much C90 code is out there, but it has to
be /at least/ in the region of 10^9 LOC, much of it in the
military arena, medical applications, and particularly the world
of comms. Letting C90 compilers fall off the radar (e.g. by
society forgetting how to program in it) really could be a
stupendously bad idea, for all the reasons that people overlook
when they shrug and say `I expect it'll all turn out fine'.
And all the existing C compilers in the entire planet support
the C90 dialect[*], if so instructed. Where is the problem?
[*] Well, except perhap Bart's and various hobby compilers.
On Wed, 21 May 2025 19:23:45 +1000, Paul Edwards wrote:
"Lawrence D'Oliveiro" <ldo@nz.invalid> wrote in message news:100j8t8$2g75r$5@dont-email.me...
On Wed, 21 May 2025 07:41:12 +1000, Paul Edwards wrote:
Basically the software industry is a joke. The advances have all been
done by hardware engineers.
Didn't they use software to manage that?
Yes - as the guy (Jeff) said - software written by lunatics/artists.
Was RCU invented by the hardware guys, or the software guys?
What about journalling? Two-phase commit? Diffie-Hellman? RSA? Kerberos? kexec?
On Mon, 26 May 2025 11:50:30 +1000, Paul Edwards wrote:
"Lawrence D'Oliveiro" <ldo@nz.invalid> wrote in message news:1010bqn$1l25r$1@dont-email.me...
On Mon, 26 May 2025 09:48:46 +1000, Paul Edwards wrote:
"people nowadays" don't speak with one voice.
Nor with one language. Which is why we have Unicode.
Which is one solution to the problem.
Just not a solution I agree with.
It's the one most of the nations of the world agree with.
I prefer VISCII-like, possibly requiring a 9-bit char, and invalidating
all applications with POSIX assumptions.
Are you going to set up your own UN as well? You could call it the "World Series of Nations" ...
This really is a very simple point, but perhaps a simple analogy will
help to clarify it. You don't throw out your 3/4" just because you've
bought a 19mm. There is room for both in the toolbox, and why write 3/4"
on your new spanner? It /isn't/ a 3/4" spanner even though it's very
like it, so why pretend otherwise?
On 29/05/2025 14:38, Richard Heathfield wrote:
This really is a very simple point, but perhaps a simple
analogy will help to clarify it. You don't throw out your 3/4"
just because you've bought a 19mm. There is room for both in
the toolbox, and why write 3/4" on your new spanner? It /isn't/
a 3/4" spanner even though it's very like it, so why pretend
otherwise?
Your analogy does not cover C99 vs C90.
On 30/05/2025 10:20, David Brown wrote:
On 29/05/2025 14:38, Richard Heathfield wrote:
This really is a very simple point, but perhaps a simple analogy will
help to clarify it. You don't throw out your 3/4" just because you've
bought a 19mm. There is room for both in the toolbox, and why write
3/4" on your new spanner? It /isn't/ a 3/4" spanner even though it's
very like it, so why pretend otherwise?
Your analogy does not cover C99 vs C90.
It does if we can construct a program that is legal C90 but not legal
C99, which is easy enough, or (slightly harder but still not that hard)
a program that is legal in both dialects but which gives different
output under C99 than it does for C90.
$ cat c9099.c;gcc -W -Wall -ansi -pedantic -o c90 c9099.c;gcc -o c99 c9099.c;./c90;./c99
#include <stdio.h>
int main(void)
{
int a = 42;
int b = a //* comment */ 6;
;
printf("Soln = %d\n", b);
return 0;
}
Soln = 7
Soln = 42
Obviously it's a contrived example, but then examples pointing out the consequences of language differences invariably are.
On 30/05/2025 12:54, Richard Heathfield wrote:
Obviously it's a contrived example, but then examples pointing
out the consequences of language differences invariably are.
The analogy there is like complaining you can't use the back end
of your new spanner to hammer in nails, because it now has a
box/ring at the end.
On 29/05/2025 22:50, Keith Thompson wrote:
Richard Heathfield <rjh@cpax.org.uk> writes:
On 29/05/2025 21:45, Keith Thompson wrote:
C99 is also exactly the same as itself.
Yes, but it's different from C99.
I hope that was a typo. If you really meant that C99 is different from
C99, I suggest that requires a bit more explanation.
Typo, of course. (9 is next to 0.) Alas, my typo-free days are over.
On 30/05/2025 15:02, David Brown wrote:
On 30/05/2025 12:54, Richard Heathfield wrote:
<snip>
Obviously it's a contrived example, but then examples pointing out
the consequences of language differences invariably are.
The analogy there is like complaining you can't use the back end of
your new spanner to hammer in nails, because it now has a box/ring at
the end.
Your argument now appears to be that people wouldn't need C90 if only
they'd written their C90 in such a way that C99 would have met their needs.
This is undoubtedly the case.
On 30/05/2025 01:05, Richard Heathfield wrote:
Typo, of course. (9 is next to 0.) Alas, my typo-free days are over.
You are, I believe, older than me. At what age can I expect my typo-
free days to start?
On 30/05/2025 01:05, Richard Heathfield wrote:
On 29/05/2025 22:50, Keith Thompson wrote:
Richard Heathfield <rjh@cpax.org.uk> writes:
On 29/05/2025 21:45, Keith Thompson wrote:
C99 is also exactly the same as itself.
Yes, but it's different from C99.
I hope that was a typo. If you really meant that C99 is
different from
C99, I suggest that requires a bit more explanation.
Typo, of course. (9 is next to 0.) Alas, my typo-free days are
over.
You are, I believe, older than me. At what age can I expect my
typo-free days to start?
:-)
I can't see how you get that from what I wrote.
I'm not sure we are getting anywhere with this thread...
On 30/05/2025 16:37, David Brown wrote:
On 30/05/2025 01:05, Richard Heathfield wrote:
Typo, of course. (9 is next to 0.) Alas, my typo-free days are
over.
You are, I believe, older than me. At what age can I expect my
typo- free days to start?
Typo free days to /end/
On 29/05/2025 14:38, Richard Heathfield wrote:
This really is a very simple point, but perhaps a simple analogy will
help to clarify it. You don't throw out your 3/4" just because you've
bought a 19mm. There is room for both in the toolbox, and why write 3/4"
on your new spanner? It /isn't/ a 3/4" spanner even though it's very
like it, so why pretend otherwise?
Your analogy does not cover C99 vs C90.
You have a good 3/4" spanner. You don't throw it out just because you
also get an adjustable spanner - sometimes the 3/4" spanner is more practical, or perhaps a bit stronger. That's keeping C when you also
have C++ available.
(The competition for first place being IBM's C compiler for z/OS)
On Tue, 20 May 2025 16:06:19 +1000, Paul Edwards wrote:
And in essence, when you read from a directory, the only thing you get
is the filename.
You want at least the type of entry as well, surely.
<https://manpages.debian.org/readdir(3)>
Am 20.05.2025 um 09:27 schrieb Lawrence D'Oliveiro:
On Tue, 20 May 2025 16:06:19 +1000, Paul Edwards wrote:
And in essence, when you read from a directory, the only thing you get
is the filename.
You want at least the type of entry as well, surely.
<https://manpages.debian.org/readdir(3)>
Easier to handle: https://en.cppreference.com/w/cpp/filesystem/directory_iterator.html
On Sat, 31 May 2025 08:20:33 +0200, Bonita Montero wrote:
Easier to handle:
https://en.cppreference.com/w/cpp/filesystem/directory_iterator.html
If you’re wanting language-specific facilities, then see if you can beat this <https://docs.python.org/3/library/os.html#os.walk>.
For one thing, notice how it gives you the choice of whether to follow symlinks or not?
Am 31.05.2025 um 23:42 schrieb Lawrence D'Oliveiro:
On Sat, 31 May 2025 08:20:33 +0200, Bonita Montero wrote:
Easier to handle:
https://en.cppreference.com/w/cpp/filesystem/directory_iterator.html
If you’re wanting language-specific facilities, then see if you can
beat this <https://docs.python.org/3/library/os.html#os.walk>. For
one thing, notice how it gives you the choice of whether to follow
symlinks or not?
Sth. like this:
for( directory_entry const &de : recursive_directory_iterator( "\\", directory_options::follow_directory_symlink ) )
cout << de.path() << endl;
On Sun, 1 Jun 2025 07:58:54 +0200, Bonita Montero wrote:
Sth. like this:
for( directory_entry const &de : recursive_directory_iterator( "\\",
directory_options::follow_directory_symlink ) )
cout << de.path() << endl;
You need the dirfd functions to avoid certain potential security holes
on operations with symlinks.
Am 01.06.2025 um 09:43 schrieb Lawrence D'Oliveiro:
On Sun, 1 Jun 2025 07:58:54 +0200, Bonita Montero wrote:
Sth. like this:
for( directory_entry const &de : recursive_directory_iterator( "\\", >>> directory_options::follow_directory_symlink ) )
cout << de.path() << endl;
You need the dirfd functions to avoid certain potential security holes
on operations with symlinks.
Which security holes ?
Bonita Montero <Bonita.Montero@gmail.com> writes:....
Am 01.06.2025 um 09:43 schrieb Lawrence D'Oliveiro:
You need the dirfd functions to avoid certain potential security holes
on operations with symlinks.
Which security holes ?
The fchownat() function shall be equivalent to the chown() and lchown() functions except in the case where path specifies a relative path. In
this case the file to be changed is determined relative to the directory associated with the file descriptor fd instead of the current working directory. If the access mode of the open file description associated
with the file descriptor is not O_SEARCH, the function shall check
whether directory searches are permitted using the current permissions
of the directory underlying the file descriptor. If the access mode is O_SEARCH, the function shall not perform the check.
Similiter for fstatat, faccessat, fchownat, openat, readlinkat et alia.
On 6/2/25 11:24, Scott Lurndal wrote:
Bonita Montero <Bonita.Montero@gmail.com> writes:...
Am 01.06.2025 um 09:43 schrieb Lawrence D'Oliveiro:
You need the dirfd functions to avoid certain potential security holes >>>> on operations with symlinks.
Which security holes ?
The fchownat() function shall be equivalent to the chown() and lchown()
functions except in the case where path specifies a relative path. In
this case the file to be changed is determined relative to the directory
associated with the file descriptor fd instead of the current working
directory. If the access mode of the open file description associated
with the file descriptor is not O_SEARCH, the function shall check
whether directory searches are permitted using the current permissions
of the directory underlying the file descriptor. If the access mode is
O_SEARCH, the function shall not perform the check.
Similiter for fstatat, faccessat, fchownat, openat, readlinkat et alia.
That describes what the functions do, it doesn't explain the potential >security holes that they avoid. The hole might seem obvious to you, but
it's certainly not obvious to me - probably because writing code to
traverse directories is something I've almost never had to do.
Am 01.06.2025 um 09:43 schrieb Lawrence D'Oliveiro:
On Sun, 1 Jun 2025 07:58:54 +0200, Bonita Montero wrote:
Sth. like this:
for( directory_entry const &de : recursive_directory_iterator( "\\", >>> directory_options::follow_directory_symlink ) )
cout << de.path() << endl;
You need the dirfd functions to avoid certain potential security
holes on operations with symlinks.
Which security holes ?
From the posix standard:
"The purpose of the fstatat() function is to obtain the status
of files in directories other than the current working directory
without exposure to race conditions. Any part of the path of a
file could be changed in parallel to a call to stat(), resulting
in unspecified behavior. By opening a file descriptor for the target
directory and using the fstatat() function it can be guaranteed that
the file for which status is returned is located relative to the desired directory."
Bonita Montero <Bonita.Montero@gmail.com> writes:
Am 01.06.2025 um 09:43 schrieb Lawrence D'Oliveiro:
On Sun, 1 Jun 2025 07:58:54 +0200, Bonita Montero wrote:
Sth. like this:
for( directory_entry const &de : recursive_directory_iterator( "\\", >>>> directory_options::follow_directory_symlink ) )
cout << de.path() << endl;
You need the dirfd functions to avoid certain potential security holes
on operations with symlinks.
Which security holes ?
The fchownat() function shall be equivalent to the chown() and lchown()
functions except in the case where path specifies a relative path. In
this case the file to be changed is determined relative to the directory
associated with the file descriptor fd instead of the current working
directory. If the access mode of the open file description associated
with the file descriptor is not O_SEARCH, the function shall check
whether directory searches are permitted using the current permissions
of the directory underlying the file descriptor. If the access mode is
O_SEARCH, the function shall not perform the check.
Am 02.06.2025 um 17:24 schrieb Scott Lurndal:
Bonita Montero <Bonita.Montero@gmail.com> writes:
Am 01.06.2025 um 09:43 schrieb Lawrence D'Oliveiro:
On Sun, 1 Jun 2025 07:58:54 +0200, Bonita Montero wrote:
Sth. like this:
for( directory_entry const &de : recursive_directory_iterator( "\\", >>>>> directory_options::follow_directory_symlink ) )
cout << de.path() << endl;
You need the dirfd functions to avoid certain potential security holes >>>> on operations with symlinks.
Which security holes ?
The fchownat() function shall be equivalent to the chown() and lchown() >> functions except in the case where path specifies a relative path. In
this case the file to be changed is determined relative to the directory >> associated with the file descriptor fd instead of the current working
directory. If the access mode of the open file description associated
with the file descriptor is not O_SEARCH, the function shall check
whether directory searches are permitted using the current permissions >> of the directory underlying the file descriptor. If the access mode is >> O_SEARCH, the function shall not perform the check.
And why is this relevant for directory_iterator or >recursive_directory_iterator ?
On Fri, 30 May 2025 18:18:43 +1000, Paul Edwards wrote:
(The competition for first place being IBM's C compiler for z/OS)
Come on, who writes C code for z/OS?
Mainframes are supposed to be all
about COBOL code, aren't they? Or so we keep being told.
And what might IBM's COBOL compiler (and associated system utilities) be written in? Why, its long-time systems-programming language of choice,
PL/I.
"Lawrence D'Oliveiro" <ldo@nz.invalid> wrote in message
And I know what you're thinking - all the data is in EBCDIC.
There are no other EBCDIC systems I could possibly jump to.
"Paul Edwards" <mutazilah@gmail.com> writes:
"Lawrence D'Oliveiro" <ldo@nz.invalid> wrote in message
And I know what you're thinking - all the data is in EBCDIC.
There are no other EBCDIC systems I could possibly jump to.
Except for various Unisys systems, which are still being sold.
And I know what you're thinking - all the data is in EBCDIC.
There are no other EBCDIC systems I could possibly jump to.
We would need an 80386 EBCDIC version of Win32 in order
for this to be remotely possible - which doesn't exist, and likely
never will exist.
For it to exist it would need some sort of pseudo-bios concept
that allowed charset conversion. And no such thing exists as far
as I am aware!
On 04/06/2025 11:23, Paul Edwards wrote:
And I know what you're thinking - all the data is in EBCDIC.
There are no other EBCDIC systems I could possibly jump to.
We would need an 80386 EBCDIC version of Win32 in order
for this to be remotely possible - which doesn't exist, and likely
never will exist.
For it to exist it would need some sort of pseudo-bios concept
that allowed charset conversion. And no such thing exists as far
as I am aware!
You don't need an EBCDIC operating system, or "pseudo-bios" (whatever
/that/ might be) to use data using EBCDIC character encoding. It is no different from working with any other character encoding - ASCII, UTF-8, different 8-bit code pages, or whatever. If the data is just passing through your code, read it in and pass it out without a care. If you
need to convert it or mix it with some other encoding, work with a
common encoding - UTF-8 is normally the right choice.
On 04/06/2025 11:23, Paul Edwards wrote:
And I know what you're thinking - all the data is in EBCDIC.
There are no other EBCDIC systems I could possibly jump to.
We would need an 80386 EBCDIC version of Win32 in order
for this to be remotely possible - which doesn't exist, and likely
never will exist.
For it to exist it would need some sort of pseudo-bios concept
that allowed charset conversion. And no such thing exists as far
as I am aware!
You don't need an EBCDIC operating system, or "pseudo-bios" (whatever
/that/ might be) to use data using EBCDIC character encoding. It is no different from working with any other character encoding - ASCII, UTF-8, different 8-bit code pages, or whatever. If the data is just passing
through your code, read it in and pass it out without a care. If you
need to convert it or mix it with some other encoding, work with a
common encoding - UTF-8 is normally the right choice.
If I have existing C code that does:
fopen("test1.dat", "rb");
fread into buf
if (memcmp(buf + 5, "XYZ", 3) == 0)
and test1.dat is in EBCDIC, the above program on the 80386
has been compiled with EBCDIC strings, so it works, and then
now you do:
printf("It matches!\n");
where do you expect those characters in the printf string - all
currently EBCDIC - to be translated to ASCII on a modern
Windows 10/11 system?
On 2025-06-04, Paul Edwards <mutazilah@gmail.com> wrote:
If I have existing C code that does:
fopen("test1.dat", "rb");
fread into buf
if (memcmp(buf + 5, "XYZ", 3) == 0)
and test1.dat is in EBCDIC, the above program on the 80386
has been compiled with EBCDIC strings, so it works, and then
now you do:
printf("It matches!\n");
where do you expect those characters in the printf string - all
currently EBCDIC - to be translated to ASCII on a modern
Windows 10/11 system?
I think that in this case you would ideally want the EBCDIC-enabled
compiler to have extensions for working with both character sets.
For isntance E"foo" would specify a string object that is
encoded in EBCDIC in the execution environment, whereas
"foo" is ASCII.
You could develop a textual preprocesor which implements
this transformation: tokenizes the C well enough to recognize
string literals preceded by E, and translates them to
string literals without E, whose content is EBCDIC bytes.
It wouldn't have to be absoultely perfect; only to work
correctly on your small amount of private code.
On 04.06.25 17:30, David Brown wrote:
On 04/06/2025 11:23, Paul Edwards wrote:
And I know what you're thinking - all the data is in EBCDIC.
There are no other EBCDIC systems I could possibly jump to.
We would need an 80386 EBCDIC version of Win32 in order
for this to be remotely possible - which doesn't exist, and likely
never will exist.
For it to exist it would need some sort of pseudo-bios concept
that allowed charset conversion. And no such thing exists as far
as I am aware!
You don't need an EBCDIC operating system, or "pseudo-bios" (whatever
/that/ might be) to use data using EBCDIC character encoding. It is no
different from working with any other character encoding - ASCII, UTF-8,
different 8-bit code pages, or whatever. If the data is just passing
through your code, read it in and pass it out without a care. If you
need to convert it or mix it with some other encoding, work with a
common encoding - UTF-8 is normally the right choice.
This might be true if there were no special characters, but eg the slash
is 2FH in ASCII but 61H in EBCDIC, so Linux may have a problem there.
The backslash is 0E0H in EBCDIC (at least in Australia, Brasil, Canada,
and various other countries), 0ECH in Germany and Austria while it is
5CH in ASCII. So DOS and Windows have a problem here.
So, YES, the operating system has to be aware of the code set used.
"Kaz Kylheku" <643-408-1753@kylheku.com> wrote in message news:20250604121550.286@kylheku.com...
On 2025-06-04, Paul Edwards <mutazilah@gmail.com> wrote:
If I have existing C code that does:
fopen("test1.dat", "rb");
fread into buf
if (memcmp(buf + 5, "XYZ", 3) == 0)
and test1.dat is in EBCDIC, the above program on the 80386
has been compiled with EBCDIC strings, so it works, and then
now you do:
printf("It matches!\n");
where do you expect those characters in the printf string - all
currently EBCDIC - to be translated to ASCII on a modern
Windows 10/11 system?
I think that in this case you would ideally want the EBCDIC-enabled
compiler to have extensions for working with both character sets.
For isntance E"foo" would specify a string object that is
encoded in EBCDIC in the execution environment, whereas
"foo" is ASCII.
You could develop a textual preprocesor which implements
this transformation: tokenizes the C well enough to recognize
string literals preceded by E, and translates them to
string literals without E, whose content is EBCDIC bytes.
It wouldn't have to be absoultely perfect; only to work
correctly on your small amount of private code.
Even assuming the above was technically possible - what's
wrong with just having a pseudo-bios and OS so that
everything is totally clean?
"Lawrence D'Oliveiro" <ldo@nz.invalid> wrote in message news:101dac8$mkpm$3@dont-email.me...
Mainframes are supposed to be all about COBOL code, aren't they? Or so
we keep being told.
That would make the IBM COBOL compiler the most important compiler in
the world, not the most important C compiler in the world.
On Wed, 4 Jun 2025 19:23:42 +1000, Paul Edwards wrote:
Most of the remaining COBOL code nowadays is compiled with ... wait for
it ... GNU COBOL. And the GNU compiler suite is, I believe, written in C++ >at its core these days (used to be C).
On 04.06.25 17:30, David Brown wrote:
On 04/06/2025 11:23, Paul Edwards wrote:
And I know what you're thinking - all the data is in EBCDIC.
There are no other EBCDIC systems I could possibly jump to.
We would need an 80386 EBCDIC version of Win32 in order
for this to be remotely possible - which doesn't exist, and likely
never will exist.
For it to exist it would need some sort of pseudo-bios concept
that allowed charset conversion. And no such thing exists as far
as I am aware!
You don't need an EBCDIC operating system, or "pseudo-bios" (whatever
/that/ might be) to use data using EBCDIC character encoding. It is
no different from working with any other character encoding - ASCII,
UTF-8, different 8-bit code pages, or whatever. If the data is just
passing through your code, read it in and pass it out without a care.
If you need to convert it or mix it with some other encoding, work
with a common encoding - UTF-8 is normally the right choice.
This might be true if there were no special characters, but eg the slash
is 2FH in ASCII but 61H in EBCDIC, so Linux may have a problem there.
The backslash is 0E0H in EBCDIC (at least in Australia, Brasil, Canada,
and various other countries), 0ECH in Germany and Austria while it is
5CH in ASCII. So DOS and Windows have a problem here.
So, YES, the operating system has to be aware of the code set used.
"David Brown" <david.brown@hesbynett.no> wrote in message news:101poqm$t350$1@dont-email.me...
On 04/06/2025 11:23, Paul Edwards wrote:
And I know what you're thinking - all the data is in EBCDIC.
There are no other EBCDIC systems I could possibly jump to.
We would need an 80386 EBCDIC version of Win32 in order
for this to be remotely possible - which doesn't exist, and likely
never will exist.
For it to exist it would need some sort of pseudo-bios concept
that allowed charset conversion. And no such thing exists as far
as I am aware!
You don't need an EBCDIC operating system, or "pseudo-bios" (whatever
/that/ might be) to use data using EBCDIC character encoding. It is no
different from working with any other character encoding - ASCII, UTF-8,
different 8-bit code pages, or whatever. If the data is just passing
through your code, read it in and pass it out without a care. If you
need to convert it or mix it with some other encoding, work with a
common encoding - UTF-8 is normally the right choice.
If I have existing C code that does:
fopen("test1.dat", "rb");
fread into buf
if (memcmp(buf + 5, "XYZ", 3) == 0)
and test1.dat is in EBCDIC, the above program on the 80386
has been compiled with EBCDIC strings, so it works, and then
now you do:
printf("It matches!\n");
where do you expect those characters in the printf string - all
currently EBCDIC - to be translated to ASCII on a modern
Windows 10/11 system?
And how do you expect Windows 10/11 to find "test1.dat" -
all EBCDIC on its current ASCII filesystem?
On 04/06/2025 20:58, Paul Edwards wrote:UTF-8,
"David Brown" <david.brown@hesbynett.no> wrote in message news:101poqm$t350$1@dont-email.me...
On 04/06/2025 11:23, Paul Edwards wrote:
And I know what you're thinking - all the data is in EBCDIC.
There are no other EBCDIC systems I could possibly jump to.
We would need an 80386 EBCDIC version of Win32 in order
for this to be remotely possible - which doesn't exist, and likely
never will exist.
For it to exist it would need some sort of pseudo-bios concept
that allowed charset conversion. And no such thing exists as far
as I am aware!
You don't need an EBCDIC operating system, or "pseudo-bios" (whatever
/that/ might be) to use data using EBCDIC character encoding. It is no
different from working with any other character encoding - ASCII,
different 8-bit code pages, or whatever. If the data is just passing
through your code, read it in and pass it out without a care. If you
need to convert it or mix it with some other encoding, work with a
common encoding - UTF-8 is normally the right choice.
If I have existing C code that does:
fopen("test1.dat", "rb");
fread into buf
if (memcmp(buf + 5, "XYZ", 3) == 0)
and test1.dat is in EBCDIC, the above program on the 80386
has been compiled with EBCDIC strings, so it works, and then
now you do:
printf("It matches!\n");
where do you expect those characters in the printf string - all
currently EBCDIC - to be translated to ASCII on a modern
Windows 10/11 system?
In /your/ code!
/You/ are responsible for writing the code that handles the data, and
which gets the encoding right. If you want to handle data in an odd encoding, write code to handle it. That's what everyone else does when dealing with data in different encodings.
And how do you expect Windows 10/11 to find "test1.dat" -
all EBCDIC on its current ASCII filesystem?
Convert the character encoding for the string.
People do this all the time. They write code that uses UTF-8, and have
to deal with Windows crappy UCS2 / partial UTF-16 / wchar_t mess. Or
they have code that supports different code pages because they started
it in the pre-Unicode days and don't live in a little American-only
ASCII bubble.
C does not make this stuff particularly convenient, though it has
improved a little since C90 - other languages have vastly superior
string and encoding handling. But that does not mean you can't do it,
or should not do it.
Maybe if you actually wanted to contribute something useful to the C
world - something that other people might find useful - you could put
your efforts into writing a library that has functions for converting encodings back and forth with UTF-8 as the base. Include support for
the dozen different EDBDIC versions.
Or do you really think that if someone sent me a file to read that was
in EDBDIC encoding, I'd be happy to install an EDBDIC "pseudo-bios" and EDBDIC version of Windows so that I could read it?
On 2025-06-04, Paul Edwards <mutazilah@gmail.com> wrote:
"Kaz Kylheku" <643-408-1753@kylheku.com> wrote in message news:20250604121550.286@kylheku.com...
On 2025-06-04, Paul Edwards <mutazilah@gmail.com> wrote:
If I have existing C code that does:
fopen("test1.dat", "rb");
fread into buf
if (memcmp(buf + 5, "XYZ", 3) == 0)
and test1.dat is in EBCDIC, the above program on the 80386
has been compiled with EBCDIC strings, so it works, and then
now you do:
printf("It matches!\n");
where do you expect those characters in the printf string - all
currently EBCDIC - to be translated to ASCII on a modern
Windows 10/11 system?
I think that in this case you would ideally want the EBCDIC-enabled
compiler to have extensions for working with both character sets.
For isntance E"foo" would specify a string object that is
encoded in EBCDIC in the execution environment, whereas
"foo" is ASCII.
You could develop a textual preprocesor which implements
this transformation: tokenizes the C well enough to recognize
string literals preceded by E, and translates them to
string literals without E, whose content is EBCDIC bytes.
It wouldn't have to be absoultely perfect; only to work
correctly on your small amount of private code.
Even assuming the above was technically possible - what's
wrong with just having a pseudo-bios and OS so that
everything is totally clean?
Nothing; it's just that the OS doesn't match the requirement given in
some above quoted text I was responding to that this is on "modern
Windows 10/11 system" which requires the program output to be
"translated to ASCII".
Maybe if you actually wanted to contribute something useful to the C
world - something that other people might find useful
Maybe if you actually wanted to contribute something useful to the C
world - something that other people might find useful - you could put
your efforts into writing a library that has functions for converting encodings back and forth with UTF-8 as the base. Include support for
the dozen different EDBDIC versions.
Bonita Montero <Bonita.Montero@gmail.com> writes:
Am 02.06.2025 um 17:24 schrieb Scott Lurndal:
Bonita Montero <Bonita.Montero@gmail.com> writes:
Am 01.06.2025 um 09:43 schrieb Lawrence D'Oliveiro:
On Sun, 1 Jun 2025 07:58:54 +0200, Bonita Montero wrote:
Sth. like this:
for( directory_entry const &de : recursive_directory_iterator( "\\", >>>>>> directory_options::follow_directory_symlink ) )
cout << de.path() << endl;
You need the dirfd functions to avoid certain potential security holes >>>>> on operations with symlinks.
Which security holes ?
The fchownat() function shall be equivalent to the chown() and lchown()
functions except in the case where path specifies a relative path. In >>> this case the file to be changed is determined relative to the directory
associated with the file descriptor fd instead of the current working >>> directory. If the access mode of the open file description associated >>> with the file descriptor is not O_SEARCH, the function shall check
whether directory searches are permitted using the current permissions >>> of the directory underlying the file descriptor. If the access mode is >>> O_SEARCH, the function shall not perform the check.
And why is this relevant for directory_iterator or
recursive_directory_iterator ?
Why are you asking this question on comp.lang.c?
Am 03.06.2025 um 20:25 schrieb Scott Lurndal:
The fchownat() function shall be equivalent to the chown() and lchown()
functions except in the case where path specifies a relative path. In >>>> this case the file to be changed is determined relative to the directory
associated with the file descriptor fd instead of the current working >>>> directory. If the access mode of the open file description associated >>>> with the file descriptor is not O_SEARCH, the function shall check >>>> whether directory searches are permitted using the current permissions
of the directory underlying the file descriptor. If the access mode is
O_SEARCH, the function shall not perform the check.
And why is this relevant for directory_iterator or
recursive_directory_iterator ?
Why are you asking this question on comp.lang.c?
Because you can have it easier than with opendir() / readdir().
Bonita Montero <Bonita.Montero@gmail.com> writes:
Am 03.06.2025 um 20:25 schrieb Scott Lurndal:
The fchownat() function shall be equivalent to the chown() and lchown()
functions except in the case where path specifies a relative path. In
this case the file to be changed is determined relative to the directory
associated with the file descriptor fd instead of the current working
directory. If the access mode of the open file description associated
with the file descriptor is not O_SEARCH, the function shall check >>>>> whether directory searches are permitted using the current permissions
of the directory underlying the file descriptor. If the access mode is
O_SEARCH, the function shall not perform the check.
And why is this relevant for directory_iterator or
recursive_directory_iterator ?
Why are you asking this question on comp.lang.c?
Because you can have it easier than with opendir() / readdir().
Personally, I'd use nftw to iterate over a path.
https://pubs.opengroup.org/onlinepubs/9799919799/functions/nftw.html
Am 06.06.2025 um 16:10 schrieb Scott Lurndal:
Bonita Montero <Bonita.Montero@gmail.com> writes:
Am 03.06.2025 um 20:25 schrieb Scott Lurndal:
The fchownat() function shall be equivalent to the chown() and lchown()
functions except in the case where path specifies a relative path. In
this case the file to be changed is determined relative to the directory
associated with the file descriptor fd instead of the current working
directory. If the access mode of the open file description associated
with the file descriptor is not O_SEARCH, the function shall check >>>>>> whether directory searches are permitted using the current permissions
of the directory underlying the file descriptor. If the access mode is
O_SEARCH, the function shall not perform the check.
And why is this relevant for directory_iterator or
recursive_directory_iterator ?
Why are you asking this question on comp.lang.c?
Because you can have it easier than with opendir() / readdir().
Personally, I'd use nftw to iterate over a path.
https://pubs.opengroup.org/onlinepubs/9799919799/functions/nftw.html
That would be much nicer with a lambda which can take the context
of the calling function.
Bonita Montero <Bonita.Montero@gmail.com> writes:
Am 06.06.2025 um 16:10 schrieb Scott Lurndal:
Bonita Montero <Bonita.Montero@gmail.com> writes:
Am 03.06.2025 um 20:25 schrieb Scott Lurndal:
The fchownat() function shall be equivalent to the chown() and lchown()
functions except in the case where path specifies a relative path. In
this case the file to be changed is determined relative to the directory
associated with the file descriptor fd instead of the current working
directory. If the access mode of the open file description associated
with the file descriptor is not O_SEARCH, the function shall check
whether directory searches are permitted using the current permissions
of the directory underlying the file descriptor. If the access mode is
O_SEARCH, the function shall not perform the check.
And why is this relevant for directory_iterator or
recursive_directory_iterator ?
Why are you asking this question on comp.lang.c?
Because you can have it easier than with opendir() / readdir().
Personally, I'd use nftw to iterate over a path.
https://pubs.opengroup.org/onlinepubs/9799919799/functions/nftw.html
That would be much nicer with a lambda which can take the context
of the calling function.
That's a matter of opinion.
In any case, nftw is a C function and C doesn't support lamda functions.
Am 06.06.2025 um 19:24 schrieb Scott Lurndal:n shall be equivalent to the chown() and lchown()
Bonita Montero <Bonita.Montero@gmail.com> writes:
Am 06.06.2025 um 16:10 schrieb Scott Lurndal:
Bonita Montero <Bonita.Montero@gmail.com> writes:
Am 03.06.2025 um 20:25 schrieb Scott Lurndal:=20
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 The fchownat() functio=
e case where path specifies a relative path. In=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 functions except in th=
be changed is determined relative to the directory=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 this case the file to =
le descriptor fd instead of the current working=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 associated with the fi=
ss mode of the open file description associated=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 directory. If the acce=
or is not O_SEARCH, the function shall check=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 with the file descript=
ches are permitted using the current permissions=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 whether directory sear=
lying the file descriptor. If the access mode is=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 of the directory under=
shall not perform the check.=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 O_SEARCH, the function=
l=20=20=20=20
And why is this relevant for directory_iterator or recursive_directory_iterator ?
Why are you asking this question on comp.lang.c?
Because you can have it easier than with opendir() / readdir().
Personally, I'd use nftw to iterate over a path.
=20
https://pubs.opengroup.org/onlinepubs/9799919799/functions/nftw.htm=
=20=20=20
That would be much nicer with a lambda which can take the context
of the calling function.
=20
That's a matter of opinion.
It results in much less code.=C2=A0
Just like a lambda passed..
to std::sort() which takes context of the calling function.
=20
In any case, nftw is a C function and C doesn't support lamda functions=
=20
Lambdas without capture can be converted to C function-pointers.
On 2025-05-28, Michael S <already5chosen@yahoo.com> wrote:
Got it. Stability occurs when the standards is fenced from
changes by presence of the next edition.
Each technical corrigendum effectively yields a new edition.
The previous standard without that corrigendum is forever stable,
as any immutable object.
On Tue, 27 May 2025 16:16:50 -0700
Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
Michael S <already5chosen@yahoo.com> writes:
On Tue, 27 May 2025 16:23:22 +0200
David Brown <david.brown@hesbynett.no> wrote:
On 26/05/2025 07:19, Peter 'Shaggy' Haywood wrote:
Groovy hepcat Tim Rentsch was jivin' in comp.lang.c on Fri, 23 May
2025 10:43 pm. It's a cool scene! Dig it.
C99 is just as stable as C90, and has been for well over a
decade.
Methinks Tim is having trouble with his arithmetic. Either
that or he doesn't know what year it is now. :)
C99 was ratified in 1999, over two and a half decades ago.
C11 is just as stable as C90, and has been for just slightly
less than a decade.
And C11 was ratified in 2011, no? That was almost a decade
and a half ago.
Tim was, I believe, taking into account the time it took for common
implementations of C compilers and libraries to have complete and
generally bug-free support for the standards, and for these
implementations to become common. C99 was published in 1999, but
it took quite a while before most people programming in C could
happily use C99 without worrying about the tool support being
"experimental" or not as mature as C90 support.
I believe that your belief is wrong.
It is much more likely that Tim took into account defect reports.
Here is the list of C11 defect reports with the last dated 2016:
https://open-std.org/jtc1/sc22/wg14/www/docs/summary.htm
I did not find similar list for C99. However believing Tim I would
guess that the last change in C99 document was made ~15 years ago.
You are partly right. Besides defect reports, there are TCs. And
there is always the possibility of future TCs, future defect
reports, or future changes for any ISO C standard while it is
still current.
To be as stable as C90, a C standard would need to be immune to
the possibility of such future changes.
I take C99 to have reached this level of stability in 2011, when
it was superseded by C11. I take C11 to have reached this level
of stability in 2017, when it was superseded by C17.
Got it. Stability occurs when the standards is fenced from
changes by presence of the next edition.
Stability by obsolescence.
On Fri, 2025-06-06 at 19:26 +0200, Bonita Montero wrote:
Am 06.06.2025 um 19:24 schrieb Scott Lurndal:
Bonita Montero <Bonita.Montero@gmail.com> writes:
Am 06.06.2025 um 16:10 schrieb Scott Lurndal:
Bonita Montero <Bonita.Montero@gmail.com> writes:
Am 03.06.2025 um 20:25 schrieb Scott Lurndal:
The fchownat() function shall be equivalent to the chown() and lchown()
functions except in the case where path specifies a relative path. In
this case the file to be changed is determined relative to the directory
associated with the file descriptor fd instead of the current working
directory. If the access mode of the open file description associated
with the file descriptor is not O_SEARCH, the function shall check
whether directory searches are permitted using the current permissions
of the directory underlying the file descriptor. If the access mode is
O_SEARCH, the function shall not perform the check.
And why is this relevant for directory_iterator or
recursive_directory_iterator ?
Why are you asking this question on comp.lang.c?
Because you can have it easier than with opendir() / readdir().
Personally, I'd use nftw to iterate over a path.
https://pubs.opengroup.org/onlinepubs/9799919799/functions/nftw.html
That would be much nicer with a lambda which can take the context
of the calling function.
That's a matter of opinion.
It results in much less code.
That is illusion, particularly in this case (about directory).
Most serious programs will 'invent' their own functions, even their own 'sugar syntax'...
'sugar syntax'... result would be better than 'directory_iterator'.
In general, no need for such things as 'directory_iterator' in C-library.
Just like a lambda passed
to std::sort() which takes context of the calling function.
In any case, nftw is a C function and C doesn't support lamda functions.
Lambdas without capture can be converted to C function-pointers.
Am 06.06.2025 um 22:04 schrieb wij:() function shall be equivalent to the chown() and lchown()
On Fri, 2025-06-06 at 19:26 +0200, Bonita Montero wrote:
Am 06.06.2025 um 19:24 schrieb Scott Lurndal:
Bonita Montero <Bonita.Montero@gmail.com> writes:
Am 06.06.2025 um 16:10 schrieb Scott Lurndal:
Bonita Montero <Bonita.Montero@gmail.com> writes:
Am 03.06.2025 um 20:25 schrieb Scott Lurndal:=20
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 The fchownat=
cept in the case where path specifies a relative path. In=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 functions ex=
e file to be changed is determined relative to the directory=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 this case th=
ith the file descriptor fd instead of the current working=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 associated w=
f the access mode of the open file description associated=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 directory. I=
e descriptor is not O_SEARCH, the function shall check=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 with the fil=
ctory searches are permitted using the current permissions=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 whether dire=
tory underlying the file descriptor. If the access mode is=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 of the direc=
e function shall not perform the check.=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 O_SEARCH, th=
).=20=20=20
And why is this relevant for directory_iterator or recursive_directory_iterator ?
Why are you asking this question on comp.lang.c?
Because you can have it easier than with opendir() / readdir(=
..html=20
Personally, I'd use nftw to iterate over a path.
=20
https://pubs.opengroup.org/onlinepubs/9799919799/functions/nftw=
=20=20=20=20=20
That would be much nicer with a lambda which can take the context
of the calling function.
=20
That's a matter of opinion.
It results in much less code.
That is illusion, particularly in this case (about directory).
I've shown the code. In C++17 iterating through a single directory and printing it is two lines of code.
Most serious programs will 'invent' their own functions, even their own 'sugar syntax'...=20
Not to iterate through a directory in C++.
=20
'sugar syntax'... result would be better than 'directory_iterator'.=20
Why ?
y.In general, no need for such things as 'directory_iterator' in C-librar=
=20
=20
In C you're forced to write ten times the code if you include error
handling.
ions.Just like a lambda passed
to std::sort() which takes context of the calling function.
=20
In any case, nftw is a C function and C doesn't support lamda funct=
=20=20
Lambdas without capture can be converted to C function-pointers.
C++ is no better, probably worse. Firstly, the term 'exception' (and
'vector' probably) is disabled in human mind to think about exception.
C++ had been trying to HIDE error (exception) from its beginning, very wrong and very unsuccessful.
Am 07.06.2025 um 13:58 schrieb wij:
=20
C++ is no better, probably worse. Firstly, the term 'exception' (and 'vector' probably) is disabled in human mind to think about exception.=20
I deal with exceptions every day and I've no problems with that. C++ exceptions aren't that clean like Java exceptions, but still make much
less work than C return code handling.
wrongC++ had been trying to HIDE error (exception) from its beginning, very =
and very unsuccessful.=20
Exceptions are the cleanest way of error handling.=C2=A0
In most cases you
deal with the error in a higher function and not in the leaf of the
call graph; therefore exceptions are perfect.
The error from opendir(..):
EACCES Permission denied.
EBADF fd is not a valid file descriptor opened for reading.
EMFILE The per-process limit on the number of open file descriptors has
been reached.
ENFILE The system-wide limit on the total number of open files has been
reached.
ENOENT Directory does not exist, or name is an empty string.
ENOMEM Insufficient memory to complete the operation.
ENOTDIR name is not a directory.
...
I think your 'less work' was from simplication or idealization, lots are simplified and idealized.
If you can handle errors that way, C can also do it in much simpler way.
The basic problem of throwing error is losing error context, it is similar
to set a global errno (or object) and cause the program to stack unwind.
C++ has many artificial fancy things and encourages such programming style. Good or bad? Both, but I would say mostly bad.
Am 07.06.2025 um 20:43 schrieb wij:d file descriptor opened for reading.
=20
The error from opendir(..):
=20
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 EACCES Permission denied. =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 EBADF=C2=A0 fd is not a vali=
limit on the number of open file descriptors has=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 EMFILE The=C2=A0 per-process=
=A0=C2=A0=C2=A0 been reached.=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
on the total number of open files has=C2=A0 been=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ENFILE The system-wide limit=
=A0=C2=A0=C2=A0 reached.=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
ist, or name is an empty string.=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ENOENT Directory does not ex=
o complete the operation.=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ENOMEM Insufficient memory t=
ory.=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ENOTDIR name is not a direct=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ...=20
With C++ that's all encapsulated in filesystem_error which is derived
from system_error. But you can omit permission denied errors with directory_options::skip_permission_denied. That makes sense mostly
with recursive_directory_iterator.=C2=A0
If you want to to that in C you'vee
at least ten times the code.
=20
I think your 'less work' was from simplication or idealization, lots ar=
..simplified and idealized.=20
No, show me your C code to iterate through a directory and I show you
the same code with up to a fifth of C++-code. When you iterate=20 recur-sively that's a tenth of the code.
=20
If you can handle errors that way, C can also do it in much simpler way=
=20lar
Absolutely not.
=20
The basic problem of throwing error is losing error context, it is simi=
..to set a global errno (or object) and cause the program to stack unwind=
=20yle.
The context doesn't matter. A bad_alloc doesn't need context, a
system_error also not. And that's most of the exceptions the C++
runtime throws (some are derived from system_error).
=20
C++ has many artificial fancy things and encourages such programming st=
Good or bad? Both, but I would say mostly bad.=20
C is bad, because you've to do simple things over and over with multiple times the code because there are no language-facilities to abstract your coding.
Am 07.06.2025 um 20:43 schrieb wij:
The basic problem of throwing error is losing error context, [...]
The context doesn't matter. A bad_alloc doesn't need context, a
system_error also not. And that's most of the exceptions the C++
runtime throws (some are derived from system_error).
I see std::filesystem as evidence that C++ finally admits the deficiency of its advance error handling system (std::exception). But the result is worse than C.
I am not familiar with C++ std lib, I cannot say much.
I see std::filesystem as evidence that C++ finally admits the deficiency of its advance error handling system (std::exception). But the result is worse
than C.
Am 07.06.2025 um 21:56 schrieb wij:
I see std::filesystem as evidence that C++ finally admits the deficiency of >> its advance error handling system (std::exception). But the result is worse
than C.
That's just a mere assertion without any facts. In fact, exception
handling makes error handling possible with a fraction of the code
length, because most parts of the code don't need to handle errors,
whereas in C they do. In C every call level has to deal with erorrs,
whereas in C++ only one level at the upper edge has to catch the
errors.
Am 07.06.2025 um 21:56 schrieb wij:y of
=20
I see std::filesystem as evidence that C++ finally admits the deficienc=
orseits advance error handling system (std::exception). But the result is w=
=C2=A0> than C.
=20
That's just a mere assertion without any facts.
In fact, exception
handling makes error handling possible with a fraction of the code
length, because most parts of the code don't need to handle errors,
whereas in C they do. In C every call level has to deal with erorrs,
whereas in C++ only one level at the upper edge has to catch the
errors.
You can of course use setjmp & longjmp in C but depending on how many levels up you jump they could be more trouble than they're worth. I think I've only ever used them once.
I know a bit of the development of std::filesystem. The view of mere 'standard'
disregards fact and uses more the 'assertion' criticized.
"dont' need" is illusion, errors are always there, mostly ignored and encouraged
to ignore by simplification.
C has not hard coded what 'exception' should be. E.g. C can also set an error object and let interested code to handle it in many ways, what's left is impl.
issues.
But, I think the 'throw' mechanism (not std::exception) is good, like many others. 'throw' is more like a soft assert failure, which is no error handling.
Am 08.06.2025 um 10:55 schrieb Muttley@DastardlyHQ.org:
You can of course use setjmp & longjmp in C but depending on how many levels >> up you jump they could be more trouble than they're worth. I think I've only >> ever used them once.
That's makes a lot of work and it's really ugly. And you need global >jump_buf-s for that.
Context, in the general case, matters. ...
It's been decades that I used C++, but back then in the 1990's
we did pass error context with the thrown error object.
That's an inherent part of C++'s exception handling. If you useMost exceptions you throw or catch are bad_allocs or system_errors.
standard error classes without context that's of course possible,
but nothing prevents you to define yet another error class derived
from some existing error class with additional information. You
are actually free to do what suits you and your projects best;
use rudimentary handling, or have a sophisticated error framework,
or anything in between.
Its no different to C++ exceptions except obviously no destructors
are called so there's no chance to do a tidy up at each stack level.
Am 08.06.2025 um 16:52 schrieb wij:tandard'
=20
I know a bit of the development of std::filesystem. The view of mere 's=
disregards fact and uses more the 'assertion' criticized.=20
Another statement without arguments.
ncouraged"dont' need" is illusion, errors are always there, mostly ignored and e=
errorto ignore by simplification.=20
If the code is written to be exception-safe, i.e. it uses
RAII throughout, then this is easily possible.
=20
C has not hard coded what 'exception' should be. E.g. C can also set an=
s impl.object and let interested code to handle it in many ways, what's left i=
anyissues.=20
Are you serious? The fact that the exception type is transported along
with the exception itself makes things really convenient. This way, the
stack can be unrolled until the correct exception handler is found.
=20
But, I think the 'throw' mechanism (not std::exception) is good, like m=
andling.others. 'throw' is more like a soft assert failure, which is no error h=
=20
Totally different - asserts are handled at debug-time.
Based on this statement, you didn't understand exceptions correctly.
On Sun, 8 Jun 2025 17:02:08 +0200
Bonita Montero <Bonita.Montero@gmail.com> wibbled:
Am 08.06.2025 um 10:55 schrieb Muttley@DastardlyHQ.org:
You can of course use setjmp & longjmp in C but depending on how many levels
up you jump they could be more trouble than they're worth. I think I've only
ever used them once.
That's makes a lot of work and it's really ugly. And you need global >>jump_buf-s for that.
Its no different to C++ exceptions except obviously no destructors are called >so there's no chance to do a tidy up at each stack level. Also jumps arn't >limited to lower to higher stack frames jumps, they can jump about all over >the place. Whether thats useful or not I can't say. I've never needed it.
Am 07.06.2025 um 23:12 schrieb Janis Papanagnou:
Context, in the general case, matters. ...
If you need the context then you catch the exception near where
it is thrown; but that's not usual, meaning in most cases you
don't need that context. F.e. when a bad_alloc is thown it dosn't
matter which allocation failed, it's just enough to know that a >memory-collapse happened.
Muttley@DastardlyHQ.org writes:
On Sun, 8 Jun 2025 17:02:08 +0200
Bonita Montero <Bonita.Montero@gmail.com> wibbled:
Am 08.06.2025 um 10:55 schrieb Muttley@DastardlyHQ.org:
You can of course use setjmp & longjmp in C but depending on how many levels
up you jump they could be more trouble than they're worth. I think I've only
ever used them once.
That's makes a lot of work and it's really ugly. And you need global >>>jump_buf-s for that.
Its no different to C++ exceptions except obviously no destructors are called >>so there's no chance to do a tidy up at each stack level. Also jumps arn't >>limited to lower to higher stack frames jumps, they can jump about all over >>the place. Whether thats useful or not I can't say. I've never needed it.
I've used sigsetjmp/siglongjmp in C++ code, very successfully. As an experiment a few
years ago, I replaced it with C++ exceptions and took a 20% performance
hit in the application. Needless to say the experiment was a failure.
In general, I tend to concur with wij - I prefer to handle run-of-the-mill errors when they're detected.
For example:^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
c_file_card_unit::c_file_card_unit(ulong channel, ulong unit, const char *name,
So, if is_ready() returns false after the constructor runs,
the creator of the object knows the creation failed.
Bonita Montero <Bonita.Montero@gmail.com> writes:
Am 07.06.2025 um 23:12 schrieb Janis Papanagnou:
Context, in the general case, matters. ...
If you need the context then you catch the exception near where
it is thrown; but that's not usual, meaning in most cases you
don't need that context. F.e. when a bad_alloc is thown it dosn't
matter which allocation failed, it's just enough to know that a
memory-collapse happened.
Actually it very much matters where the allocation failed, if
one wishes to recover from it.
It seems your concept of error
handling is simply reporting it (hopefully with sufficient
context information for the user to understand what needs to
be fixed) and calling exit().
My primary interest of programming is on the theory. ...
I've used sigsetjmp/siglongjmp in C++ code, very successfully. As an experiment a few
years ago, I replaced it with C++ exceptions and took a 20% performance
hit in the application. Needless to say the experiment was a failure.
Actually it very much matters where the allocation failed, if
one wishes to recover from it.
Am 08.06.2025 um 18:28 schrieb wij:
=20
My primary interest of programming is on the theory. ...=20
Then don't talk about practical issues.
In C every call level has to deal with erorrs, whereas in C++ only
one level at the upper edge has to catch the errors.
Am 08.06.2025 um 17:08 schrieb Muttley@DastardlyHQ.org:
Its no different to C++ exceptions except obviously no destructors
are called so there's no chance to do a tidy up at each stack level.
It's much more complicated than exceptions because the functions where
the error raises and where the error is "caught" need shared global >variables. C++ doesn't need that, just throw and catch and everything
is glued to the runtime.
And the problem with your solution is: All functions between the setjmp-
and the longjmp-calls don't have any cleanup, i.e. they don't handle
back their opened resources to the runtime or the kernel. With RAII in >combination with exceptions that's for free.
Do you really think setjmp() / longjmp() is a competitive solution ?
You're naive.
In general, I tend to concur with wij - I prefer to handle run-of-the-mill >errors when they're detected.
Did you actually read what I wrote? Obviously in C++ you'd use exceptionsI ask myself if setjmp() / longjmp() with manual unwinding then is
but in C without any kind of built in exception mechanism they're better
than nothing if you want to jump out of a deep stack.
Same here. I think with exceptions the clue is in the name. They should really
only be used for exceptional circumstances, not as a general minor error handling mechanism.
Not necessarily that simple. It might be easier if C++ had
try/finally (like Python does), but it doesn’t.
Am 08.06.2025 um 18:58 schrieb Scott Lurndal:
Actually it very much matters where the allocation failed, if
one wishes to recover from it.
This very rarely makes sense. It's almost always the case that if
an operation fails, it doesn't matter what allocation was behind
it.
Have you ever written real-world production code? Like an operating system, where allocation failures should -never- result in an
inability to recover.
Am 09.06.2025 um 16:01 schrieb Scott Lurndal:
Have you ever written real-world production code? Like an operating
system, where allocation failures should -never- result in an
inability to recover.
If you need an allocation to proceed and it fails you can't recover.
Bonita Montero <Bonita.Montero@gmail.com> writes:
Am 09.06.2025 um 16:01 schrieb Scott Lurndal:
Have you ever written real-world production code? Like an operating
system, where allocation failures should -never- result in an
inability to recover.
If you need an allocation to proceed and it fails you can't recover.
That's your problem caused by poor design and implementation.
Exacerbated by the propensity for you to use C++ features that require dynamic allocation where other forms of data structures are more suitable.
Bonita Montero <Bonita.Montero@gmail.com> writes:
Am 09.06.2025 um 16:01 schrieb Scott Lurndal:
Have you ever written real-world production code? Like an operating
system, where allocation failures should -never- result in an
inability to recover.
If you need an allocation to proceed and it fails you can't recover.
That's your problem caused by poor design and implementation.
Am 09.06.2025 um 17:53 schrieb Scott Lurndal:
Bonita Montero <Bonita.Montero@gmail.com> writes:
Am 09.06.2025 um 16:01 schrieb Scott Lurndal:
Have you ever written real-world production code? Like an operating >>>> system, where allocation failures should -never- result in an
inability to recover.
If you need an allocation to proceed and it fails you can't recover.
That's your problem caused by poor design and implementation.
That's how 100% of all programs that deal with bad_alloc are designed.
Exacerbated by the propensity for you to use C++ features that require
dynamic allocation where other forms of data structures are more suitable.
When dynamic allocation is needed it is needed.
And there are many ways to handle it that don't include throwing
bad_alloc when the system is unable to provide additional address
space, memory or backing store.
Allocating major data structures at application start (perhaps using
a pool allocator) and crafting your algorithms such that they
don't require infinite memory is a good start.
Bonita Montero <Bonita.Montero@gmail.com> writes:
Am 08.06.2025 um 18:58 schrieb Scott Lurndal:
Actually it very much matters where the allocation failed, if
one wishes to recover from it.
This very rarely makes sense. It's almost always the case that if
an operation fails, it doesn't matter what allocation was behind
it.
Have you ever written real-world production code? Like an operating system, where allocation failures should -never- result in an
inability to recover.
Bonita Montero <Bonita.Montero@gmail.com> writes:
Am 09.06.2025 um 17:53 schrieb Scott Lurndal:
Bonita Montero <Bonita.Montero@gmail.com> writes:
Am 09.06.2025 um 16:01 schrieb Scott Lurndal:
Have you ever written real-world production code? Like an operating >>>>> system, where allocation failures should -never- result in an
inability to recover.
If you need an allocation to proceed and it fails you can't recover.
That's your problem caused by poor design and implementation.
That's how 100% of all programs that deal with bad_alloc are designed.
Exacerbated by the propensity for you to use C++ features that requireWhen dynamic allocation is needed it is needed.
dynamic allocation where other forms of data structures are more suitable. >>
And there are many ways to handle it that don't include throwing
bad_alloc when the system is unable to provide additional address
space, memory or backing store.
Allocating major data structures at application start (perhaps using a
pool allocator) and crafting your algorithms such that they
don't require infinite memory is a good start.
You're talking to someone who can't understand the difference
between comp.lang.c and comp.lang.c++. What do you expect?
On 2025-06-08, Scott Lurndal <scott@slp53.sl.home> wrote:
Muttley@DastardlyHQ.org writes:
On Sun, 8 Jun 2025 17:02:08 +0200
Bonita Montero <Bonita.Montero@gmail.com> wibbled:
Am 08.06.2025 um 10:55 schrieb Muttley@DastardlyHQ.org:
You can of course use setjmp & longjmp in C but depending on how
many levels up you jump they could be more trouble than they're
worth. I think I've only ever used them once.
That's makes a lot of work and it's really ugly. And you need
global jump_buf-s for that.
setjmp and longjmp have a clearly defined implementation model
(obviously not in ISO C, but so in implementation practice).
On Mon, 2 Jun 2025 09:35:24 +0200, Bonita Montero wrote:
Am 01.06.2025 um 09:43 schrieb Lawrence D'Oliveiro:
On Sun, 1 Jun 2025 07:58:54 +0200, Bonita Montero wrote:
Sth. like this:
for( directory_entry const &de : recursive_directory_iterator( "\\", >>>> directory_options::follow_directory_symlink ) )
cout << de.path() << endl;
You need the dirfd functions to avoid certain potential security
holes on operations with symlinks.
Which security holes ?
TOCTOU.
On Mon, 09 Jun 2025 18:33:38 GMT
scott@slp53.sl.home (Scott Lurndal) wibbled:
Bonita Montero <Bonita.Montero@gmail.com> writes:
Am 09.06.2025 um 17:53 schrieb Scott Lurndal:
Bonita Montero <Bonita.Montero@gmail.com> writes:
Am 09.06.2025 um 16:01 schrieb Scott Lurndal:
Have you ever written real-world production code? Like an operating >>>>>> system, where allocation failures should -never- result in an
inability to recover.
If you need an allocation to proceed and it fails you can't recover.
That's your problem caused by poor design and implementation.
That's how 100% of all programs that deal with bad_alloc are designed.
Exacerbated by the propensity for you to use C++ features that require >>>> dynamic allocation where other forms of data structures are more suitable. >>>When dynamic allocation is needed it is needed.
And there are many ways to handle it that don't include throwing
bad_alloc when the system is unable to provide additional address
space, memory or backing store.
Allocating major data structures at application start (perhaps using a
pool allocator) and crafting your algorithms such that they
don't require infinite memory is a good start.
Ugh. Then you end up like the Java JVM - grabbing boatloads of memory that >causes huge startup delays and can often cause the machine to do lots of >swapping and/or slow everything else down to treacle.
And all the existing C compilers in the entire planet support
the C90 dialect[*], if so instructed. Where is the problem?
Am 03.06.2025 um 02:37 schrieb Lawrence D'Oliveiro:
On Mon, 2 Jun 2025 09:35:24 +0200, Bonita Montero wrote:
Am 01.06.2025 um 09:43 schrieb Lawrence D'Oliveiro:
On Sun, 1 Jun 2025 07:58:54 +0200, Bonita Montero wrote:
Sth. like this:
for( directory_entry const &de : recursive_directory_iterator( "\\", >>>>> directory_options::follow_directory_symlink ) )
cout << de.path() << endl;
You need the dirfd functions to avoid certain potential security
holes on operations with symlinks.
Which security holes ?
TOCTOU.
That's unavoidable with directory-operations.
That's unavoidable with directory-operations.
Incorrect. The entire purpose of the POSIX *at functions are to close
those security holes.
Muttley@DastardlyHQ.org writes:
Ugh. Then you end up like the Java JVM - grabbing boatloads of memory that >>causes huge startup delays and can often cause the machine to do lots of >>swapping and/or slow everything else down to treacle.
That's a problem with host not being suitable for java, if that
is the behavior you are seeing. I've not seen that in production
java-based applications that are competently developed.
For C/C++, one generally allocates page-aligned regions with mmap, eschewing >granular allocation methods such as new/delete/malloc.
Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
Richard Harnden <richard.harnden@gmail.invalid> writes:
On 22/05/2025 23:32, Keith Thompson wrote:
[...]
In one of your library's headers:
extern const char ESCAPE;
In the corresponding *.c file:
const char ESCAPE = ('z' - 'a' == 25 ? '\x1b' : '\x27');
Change the name if you prefer.
Wouldn't that be a reserved identifier?
Yes, it would. Good catch.
(Identifiers starting with E followed by either a digit or an
uppercase letter are reserved; they could be defined as macros
in <errno.h>.)
They are reserved only as macros, and only if <errno.h> has
been #include'd.
For this particular use, it's easy to make the definition work,
simply by adding
#undef ESCAPE
before the declaration in the header file, and before the
definition in the source file (assuming of course that if
there are any #include <errno.h> they precede the #undef's).
It would be even easier to pick a different name.
Bonita Montero <Bonita.Montero@gmail.com> writes:
Am 03.06.2025 um 02:37 schrieb Lawrence D'Oliveiro:
On Mon, 2 Jun 2025 09:35:24 +0200, Bonita Montero wrote:
Am 01.06.2025 um 09:43 schrieb Lawrence D'Oliveiro:
On Sun, 1 Jun 2025 07:58:54 +0200, Bonita Montero wrote:
Sth. like this:
for( directory_entry const &de : recursive_directory_iterator( "\\", >>>>>> directory_options::follow_directory_symlink ) )
cout << de.path() << endl;
You need the dirfd functions to avoid certain potential security
holes on operations with symlinks.
Which security holes ?
TOCTOU.
That's unavoidable with directory-operations.
Incorrect. The entire purpose of the POSIX *at functions are to close
those security holes.
Muttley@DastardlyHQ.org writes:
On Mon, 09 Jun 2025 18:33:38 GMT
scott@slp53.sl.home (Scott Lurndal) wibbled:
Bonita Montero <Bonita.Montero@gmail.com> writes:
Am 09.06.2025 um 17:53 schrieb Scott Lurndal:
Bonita Montero <Bonita.Montero@gmail.com> writes:
Am 09.06.2025 um 16:01 schrieb Scott Lurndal:That's your problem caused by poor design and implementation.
Have you ever written real-world production code? Like an operating >>>>>>> system, where allocation failures should -never- result in an
inability to recover.
If you need an allocation to proceed and it fails you can't recover. >>>>>
That's how 100% of all programs that deal with bad_alloc are designed. >>>>
Exacerbated by the propensity for you to use C++ features that require >>>>> dynamic allocation where other forms of data structures are more suitable.
When dynamic allocation is needed it is needed.
And there are many ways to handle it that don't include throwing
bad_alloc when the system is unable to provide additional address
space, memory or backing store.
Allocating major data structures at application start (perhaps using a
pool allocator) and crafting your algorithms such that they
don't require infinite memory is a good start.
Ugh. Then you end up like the Java JVM - grabbing boatloads of memory that >> causes huge startup delays and can often cause the machine to do lots of
swapping and/or slow everything else down to treacle.
That's a problem with host not being suitable for java, if that
is the behavior you are seeing. I've not seen that in production
java-based applications that are competently developed.
For C/C++, one generally allocates page-aligned regions with mmap, eschewing granular allocation methods such as new/delete/malloc.
Bonita Montero <Bonita.Montero@gmail.com> writes:
Am 09.06.2025 um 17:53 schrieb Scott Lurndal:
Bonita Montero <Bonita.Montero@gmail.com> writes:
Am 09.06.2025 um 16:01 schrieb Scott Lurndal:
Have you ever written real-world production code? Like an operating >>>>> system, where allocation failures should -never- result in an
inability to recover.
If you need an allocation to proceed and it fails you can't recover.
That's your problem caused by poor design and implementation.
That's how 100% of all programs that deal with bad_alloc are designed.
Exacerbated by the propensity for you to use C++ features that requireWhen dynamic allocation is needed it is needed.
dynamic allocation where other forms of data structures are more suitable. >>
And there are many ways to handle it that don't include throwing
bad_alloc when the system is unable to provide additional address
space, memory or backing store.
Allocating major data structures at application start (perhaps using a
pool allocator) and crafting your algorithms such that they
don't require infinite memory is a good start.
Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:[...]
Richard Harnden <richard.harnden@gmail.invalid> writes:
On 22/05/2025 23:32, Keith Thompson wrote:
In one of your library's headers:
extern const char ESCAPE;
In the corresponding *.c file:
const char ESCAPE = ('z' - 'a' == 25 ? '\x1b' : '\x27');
Change the name if you prefer.
Wouldn't that be a reserved identifier?
Yes, it would. Good catch.
(Identifiers starting with E followed by either a digit or an
uppercase letter are reserved; they could be defined as macros
in <errno.h>.)
They are reserved only as macros, and only if <errno.h> has
been #include'd.
For this particular use, it's easy to make the definition work,
simply by adding
#undef ESCAPE
before the declaration in the header file, and before the
definition in the source file (assuming of course that if
there are any #include <errno.h> they precede the #undef's).
It would be even easier to pick a different name.
The point of my comment was to help explain the rules about what
macro names are reserved and under what circumstances, not to
suggest a way to avoid conflicts.
A better way to avoid conflicts with E* macros is to take functions
where errno is needed, as for example signal(), and not call them
directly but rather wrap each one in a function, with the wrapping
functions put in (one or more) separate translation unit(s). Those translation units, and only those translation units, are the ones
where a #include <errno.h> is done. Some details are needed to keep
the separation complete, but I think those aren't too hard to work
out, so if someone has trouble please ask. This way most of the
program can use names beginning with E that might otherwise be
reserved, without any fear of conflicts. There is a bit of source
code overhead, but that is paid only once, across all projects that
use this approach. Also there are some other benefits, related to
libraries used that are not part of ISO C, such as Posix, which
again should be readily apparent to anyone used to working in large
projects that use such libraries.
I find the reservation of potential errno macro names annoying.
On 2025-06-10, Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
I find the reservation of potential errno macro names annoying.
If the standard contained /no/ statements about what a given header
file may reserve, then /any/ identifier whatsoever would be a potential clash.
The errno reservation is kind of good because implementors often extend
the set of errno constants. POSIX has a lot more of them than ISO C, and there are some vendor-specific ones.
Anyway, you can safely ignore the reservation theatre, and just
deal with clashes that happen, when they happen. (If you're lucky,
that could just be never).
Anyway, ISO C, POSIX and vendors have historically introduced new
identifiers in spaces that were not previously declared as reserved.
If you're ever hit by that, you will feel like a completel sucker if
you've religiously adhered to namespaces from your end.
Am 03.06.2025 um 02:37 schrieb Lawrence D'Oliveiro:\",
On Mon, 2 Jun 2025 09:35:24 +0200, Bonita Montero wrote:
Am 01.06.2025 um 09:43 schrieb Lawrence D'Oliveiro:
On Sun, 1 Jun 2025 07:58:54 +0200, Bonita Montero wrote:
Sth. like this:
for( directory_entry const &de : recursive_directory_iterator( "\
directory_options::follow_directory_symlink ) )
cout << de.path() << endl;
You need the dirfd functions to avoid certain potential security
holes on operations with symlinks.
Which security holes ?
TOCTOU.
That's unavoidable with directory-operations.
Kaz Kylheku <643-408-1753@kylheku.com> writes:
On 2025-06-10, Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
I find the reservation of potential errno macro names annoying.
If the standard contained /no/ statements about what a given header
file may reserve, then /any/ identifier whatsoever would be a potential
clash.
The errno reservation is kind of good because implementors often extend
the set of errno constants. POSIX has a lot more of them than ISO C, and
there are some vendor-specific ones.
Anyway, you can safely ignore the reservation theatre, and just
deal with clashes that happen, when they happen. (If you're lucky,
that could just be never).
You can do that, but a new clash could happen when your code is
compiled on a system that defines an errno macro that you haven't
seen before.
Anyway, ISO C, POSIX and vendors have historically introduced new
identifiers in spaces that were not previously declared as reserved.
If you're ever hit by that, you will feel like a completel sucker if
you've religiously adhered to namespaces from your end.
Yes, that can happen, but no, I won't feel like a complete sucker.
If I define my own strfoo() function and a new edition of the standard defines strfoo() in <string.h>, the clash is my fault,and I could have avoided it by defining str_foo().
On 2025-06-10, Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
Kaz Kylheku <643-408-1753@kylheku.com> writes:
On 2025-06-10, Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
I find the reservation of potential errno macro names annoying.
If the standard contained /no/ statements about what a given header
file may reserve, then /any/ identifier whatsoever would be a potential
clash.
The errno reservation is kind of good because implementors often extend
the set of errno constants. POSIX has a lot more of them than ISO C, and >>> there are some vendor-specific ones.
Anyway, you can safely ignore the reservation theatre, and just
deal with clashes that happen, when they happen. (If you're lucky,
that could just be never).
You can do that, but a new clash could happen when your code is
compiled on a system that defines an errno macro that you haven't
seen before.
A new CRASH could happen too, and any number of things.
This clash would be literally one of the first roadblocks, if not the
first one, that we would see when just exploring the possibility whether
our code might not run on that system.
At that point we could be months away from declaring that a supported platform.
Anyway, ISO C, POSIX and vendors have historically introduced new
identifiers in spaces that were not previously declared as reserved.
If you're ever hit by that, you will feel like a completel sucker if
you've religiously adhered to namespaces from your end.
Yes, that can happen, but no, I won't feel like a complete sucker.
If I define my own strfoo() function and a new edition of the standard
defines strfoo() in <string.h>, the clash is my fault,and I could have
avoided it by defining str_foo().
But, my point is, that maybe you could have called it kidneybeans() and
still have a clash.
In fact, if you are writing new string functions that are the same sort
of stuff like the standard ones, you should use the str prefix,
for consistency.
If your code is influential enough, they might be standardized one
day---and then they are ready with the proper naming, so early adopters
of your functions won't have to change anything; just in their build
system drop the third party code and switch to what their library now provides.
No it isn’t. That’s why we have the fd-based calls in recent POSIX, and in
Linux. That plugs the holes, and makes it possible to implement privileged file-access software like Samba securely.
Am 11.06.2025 um 01:33 schrieb Lawrence D'Oliveiro:
No it isn’t. That’s why we have the fd-based calls in recent POSIX, and >> in Linux. That plugs the holes, and makes it possible to implement
privileged file-access software like Samba securely.
opendir() and readdir() hasn't changed for decades.
Am 11.06.2025 um 01:33 schrieb Lawrence D'Oliveiro:
No it isn’t. That’s why we have the fd-based calls in recent POSIX, and in
Linux. That plugs the holes, and makes it possible to implement privileged >> file-access software like Samba securely.
opendir() and readdir() hasn't changed for decades.
Kaz Kylheku <643-408-1753@kylheku.com> writes:
On 2025-06-10, Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
Kaz Kylheku <643-408-1753@kylheku.com> writes:
On 2025-06-10, Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
I find the reservation of potential errno macro names annoying.
If the standard contained /no/ statements about what a given header
file may reserve, then /any/ identifier whatsoever would be a potential >>>> clash.
The errno reservation is kind of good because implementors often extend >>>> the set of errno constants. POSIX has a lot more of them than ISO C, and >>>> there are some vendor-specific ones.
Anyway, you can safely ignore the reservation theatre, and just
deal with clashes that happen, when they happen. (If you're lucky,
that could just be never).
You can do that, but a new clash could happen when your code is
compiled on a system that defines an errno macro that you haven't
seen before.
A new CRASH could happen too, and any number of things.
Sure, but a compilation failure is more likely.
This clash would be literally one of the first roadblocks, if not the
first one, that we would see when just exploring the possibility whether
our code might not run on that system.
At that point we could be months away from declaring that a supported
platform.
Sure, but why not skip that first roadblock?
Anyway, ISO C, POSIX and vendors have historically introduced new
identifiers in spaces that were not previously declared as reserved.
If you're ever hit by that, you will feel like a completel sucker if
you've religiously adhered to namespaces from your end.
Yes, that can happen, but no, I won't feel like a complete sucker.
If I define my own strfoo() function and a new edition of the standard
defines strfoo() in <string.h>, the clash is my fault,and I could have
avoided it by defining str_foo().
But, my point is, that maybe you could have called it kidneybeans() and
still have a clash.
Certainly, I've already acknowledged that.
But surely an identifier that the standard says is reserved is less
likely to cause a clash than one that isn't.
In fact, if you are writing new string functions that are the same sort
of stuff like the standard ones, you should use the str prefix,
for consistency.
If your code is influential enough, they might be standardized one
day---and then they are ready with the proper naming, so early adopters
of your functions won't have to change anything; just in their build
system drop the third party code and switch to what their library now
provides.
I see your point, but ... meh. To me, a name matching "str[a-z]*"
fairly strongly suggests a function declared in <string.h> in ISO C.
Of course it's not an absolute rule; see strlcpy(), for example
(which is now part of POSIX).
Even a str*() identifier that never clashes with ISO C's <string.h>
can still clash with POSIX, or glibc, or BSD, or ....
I would have been happier if POSIX were less intrusive on the
C standard library, but the way C and POSIX evolved didn't make
that feasible.
I find the reservation of potential errno macro names annoying.
That turns out to not be true. fdopendir(3) was added in Issue
7 of the Single Unix Specification (aka POSIX). https://pubs.opengroup.org/onlinepubs/9799919799/functions/fdopendir.html ftw(3)/nftw(3) are used more often than opendir(3) in real world code.
Kaz Kylheku <643-408-1753@kylheku.com> writes:
On 2025-06-10, Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
I find the reservation of potential errno macro names annoying.
If the standard contained /no/ statements about what a given header
file may reserve, then /any/ identifier whatsoever would be a potential
clash.
The errno reservation is kind of good because implementors often extend
the set of errno constants. POSIX has a lot more of them than ISO C, and
there are some vendor-specific ones.
Anyway, you can safely ignore the reservation theatre, and just
deal with clashes that happen, when they happen. (If you're lucky,
that could just be never).
You can do that, but a new clash could happen when your code is
compiled on a system that defines an errno macro that you haven't
seen before.
Anyway, ISO C, POSIX and vendors have historically introduced new
identifiers in spaces that were not previously declared as reserved.
If you're ever hit by that, you will feel like a completel sucker if
you've religiously adhered to namespaces from your end.
Yes, that can happen, but no, I won't feel like a complete sucker.
If I define my own strfoo() function and a new edition of the standard defines strfoo() in <string.h>, the clash is my fault,and I could have avoided it by defining str_foo().
Nothing can prevent all possible name clashes, but I like to follow the
rules in the standard that let me prevent some of them.
[fdopendir] doesn't make a difference for the discussed point.
On 28/05/2025 13:41, Tim Rentsch wrote:
Richard Heathfield <rjh@cpax.org.uk> writes:
On 24/05/2025 06:32, Tim Rentsch wrote:
Richard Heathfield <rjh@cpax.org.uk> writes:
On 23/05/2025 13:43, Tim Rentsch wrote:
Richard Heathfield <rjh@cpax.org.uk> writes:
On 20/05/2025 10:18, Keith Thompson wrote:
C90 will never be extended.
And for that reason it will always be valuable. Stability
has a value all its own.
C99 is just as stable as C90, and has been for well over a
decade.
Sure, but it's a different stable.
If it were the same stable, it would be C90.
C99 isn't C90, therefore it isn't the same stable.
If you tell me C99 is a rock, I will not doubt you. But the C90
rock it most certainly isn't.
Now you're being silly.
No, sir. If you want to play that game, you can play it with
yourself. I know that you are perfectly capable of polite
conversation, so I see no reason to endure the opposite.
I don't think I'm being impolite.
Then we are again in disagreement, and it seems obvious that it would
be foolishly optimistic of me to expect to be able to resolve the
matter. I'll tell Thunderbird to leave it there.
On 30/05/2025 10:20, David Brown wrote:
On 29/05/2025 14:38, Richard Heathfield wrote:
This really is a very simple point, but perhaps a simple analogy
will help to clarify it. You don't throw out your 3/4" just
because you've bought a 19mm. There is room for both in the
toolbox, and why write 3/4" on your new spanner? It /isn't/ a
3/4" spanner even though it's very like it, so why pretend
otherwise?
Your analogy does not cover C99 vs C90.
It does if we can construct a program that is legal C90 but not
legal C99, which is easy enough, or (slightly harder but still not
that hard) a program that is legal in both dialects but which
gives different output under C99 than it does for C90.
$ cat c9099.c; \
gcc -W -Wall -ansi -pedantic -o c90 c9099.c; \
gcc -o c99 c9099.c; \
./c90; \
./c99
#include <stdio.h>
int main(void)
{
int a = 42;
int b = a //* comment */ 6;
;
printf("Soln = %d\n", b);
return 0;
}
Soln = 7
Soln = 42
Obviously it's a contrived example, but then examples pointing out
the consequences of language differences invariably are.
"Lawrence D'Oliveiro" <ldo@nz.invalid> wrote in message news:100jhor$2lgt3$4@dont-email.me...
On Wed, 21 May 2025 10:23:27 +1000, Paul Edwards wrote:...
The C90 standard deferred to MVS - probably still does -
and says that you can't open a file as "w", then read it as
"rb" and write (a new file) as "wb", and still access (the
new file) with "r".
I was shocked when I saw IBM's C library lose the newlines
when I did the above, and went to look at the standard to
show that IBM was violating C90 - but it turns out they
weren't.
That sort of means you can't write a "zip" program portably,
against the theoretical C90 file system. Or you would have
to have flags to say which files need to be opened as text
or binary.
I do not agree with IBM's C library, and PDPCLIB does
not have that behavior, so that constraint could potentially
be dropped in a C90+ standard.
BFN. Paul.
Lawrence D'Oliveiro <ldo@nz.invalid> writes:
On Thu, 22 May 2025 02:20:36 +0200, Jakob Bohm wrote:
The later UNIX-like file system NTFS ...
It was (and is) hard to describe NTFS as “Unix-like”. Yes, it had
hierarchical directories and long(ish) file names, but not much else.
Drive letters were inherited (indirectly) from DEC OSes, of all things,
along with an insistence on having filename extensions, restrictions on
characters allowed in names etc.
I don't believe that NTFS requires filename extensions.
My understanding is that a file name is stored as a single string
(with some restrictions).
Symlinks were not even added until Windows Vista. And you have to have
special privileges to create them.
Do note one more thing.
The C90 standard deferred to MVS - probably still does -
and says that you can't open a file as "w", then read it as
"rb" and write (a new file) as "wb", and still access (the
new file) with "r".
I was shocked when I saw IBM's C library lose the newlines
when I did the above, and went to look at the standard to
show that IBM was violating C90 - but it turns out they
weren't.
That sort of means you can't write a "zip" program portably,
against the theoretical C90 file system.
Or you would have
to have flags to say which files need to be opened as text
or binary.
On 2025-05-21, Paul Edwards <mutazilah@gmail.com> wrote:....
Do note one more thing.
The C90 standard deferred to MVS - probably still does -
and says that you can't open a file as "w", then read it as
"rb" and write (a new file) as "wb", and still access (the
new file) with "r".
You mean:
- write a text file, close it; then
- open it as a binary file and copy the bytes to another, new binary file; and
- finally, read the new binary file in text mode?
I don't see how that would be allowed to lose any newlines.
You made a bitwise copy of the file.
A recent draft of ISO C says "A binary stream is an ordered sequence of characters that can transparently record internal data. Data read in
from a binary stream shall compare equal to the data that were earlier written out to that stream, under the same implementation. Such a stream
may, however, have an implementation- defined number of null characters appended to the end of the stream."
I have C90 somewhere, I can look that up too, but I suspect it was
the same.
I was shocked when I saw IBM's C library lose the newlines
when I did the above, and went to look at the standard to
show that IBM was violating C90 - but it turns out they
weren't.
Sysop: | Tetrazocine |
---|---|
Location: | Melbourne, VIC, Australia |
Users: | 11 |
Nodes: | 8 (0 / 8) |
Uptime: | 47:58:01 |
Calls: | 166 |
Files: | 21,502 |
Messages: | 77,696 |