Programming in standard c

W

William Pursell

int main(void) { int n = printf("hello\n");}
How much is n?

No way to know since the error codes of printf
are NOT standardized. This means that I can only
know that n can be... *ANYTHING*. Maybe it wrote
some characters, then stopped, or whatever!

If you want to know what n is, then you check
it. Perhaps like so:

int main(void) {
int n = printf("hello\n");
printf(" n = %d\n", n );
return 0;}


That's really not so hard.
 
D

dj3vande

<[email protected]> schreef in bericht


yes
if one decides that i;m sure there will be other unportable means to do it

So we've gone from having a non-portable way to do something that's
useful and meaningful on some systems, to having a non-portable way to
do something that's useful and meaningful on some systems.

Remind me again what the point of this exercise was?


dave
 
K

Keith Thompson

Serve La said:
How about let filesize("/var/adm/messages") and others UB?? On some
systems it could return correct values on others an error

fflush(stdin) is UB so i dont see a reason why filesize should have
every single filetype perfectly defined.
And here in clc people will have 1 more reason to tell others that
demons will fly out of their nose when they try filesize() on
/dev/random or something!

Presumably filesize("/dev/random") could behave sensibly without
invoking undefined behavior. The system could detect that it's a
"character special file" and return an error indication. An
implementation of filesize() might fall back to reading every byte of
the file in some cases, but only when necessary. There's nothing
special about filesize("/var/adm/messages"); it's just an ordinary
file whose size happens to change a lot.

The set of functions in the C standard library is not a carefully
engineered coherent interface. The choice of which functions to
include and which to exclude has been largely arbitrary. strdup() is
fairly useful and commonly provided, but it was excluded by the
standard committee back in 1989. gets() is positively dangerous, but
it was included because of historical precedent (and was finally
deprecated nearly 20 years later). strtok() has its own set of
problems. The time interfaced is incomplete (mktime() is the inverse
of localtime(), but no inverse for gmtime() is provided, and asctime()
unnecessarily invokes undefined behavior for out-of-range arguments).
And so forth.

I'll note that Ada, which was first standardized several years before
C was, does have a function to obtain the current size of a file (it
takes Ada's equivalent of a FILE*, not a file name). The designers of
Ada were as concerned with portability as the designers of C; Ada,
like C, runs on everything from small embedded systems to PCs to
mainframes and supercomputers.

A filesize() function, with all its limitations, *could* have been
included in the standard. It wasn't. If it had been, it might have
been useful in some contexts, but you'd have to be very careful in
using it. I suspect that a function that takes a FILE* would be more
useful than one that takes a file name; perhaps both could have been
provided.

But there's always POSIX, which *does* provide this functionality via
the stat() and fstat() functions. The fact is that most, perhaps all,
systems on which filesize() would make sense provide it via an
extension. Yes, it's inconvenient to have to use different interfaces
on different systems.

I have no strong opinion on whether a filesize() function *should*
have been in the C standard. The fact is that it isn't. The lack has
not been a serious problem, since the functionality is generally
available when needed. And adding it to the standard now would be a
long and slow process -- one that is not particularly helped (or hurt)
by talking about it here.

If you really want filesize() in the C standard, one way to start
making that happen is to write a proposal and post it to comp.std.c
for discussion.
 
D

dj3vande

Richard Heathfield said:
Stephen Montgomery-Smith said:

How do you feel about s/rather than/as well/ - because I think that such a
change reflects reality rather more closely.

I think I prefer to think of it in terms of C-with-extensions being a
tool to be used to supplement standard C when necessary. This is
dual[1] to Stephen's statement, and I think it more closely captures
reality than putting them on equal footing; there is a lot of useful
code that can be written in standard C in between the bits that you
need extensions for, but I've yet to encounter a problem (though they
probably exist) that doesn't have nontrivial subproblems that can (and
often should) be solved entirely with standard C. It's also worth
noting that without a well-defined (but not excessively strict)
language to build on, the extensions would be a lot harder to use and a
lot less useful.
Certainly for my own part, I
know that my use of what you call "real C" (by which you appear to mean "C
+ non-ISO9899 libraries") is dwarfed by my use of ISO C. Most of the C
programs I write are ISO C programs. Only a very small proportion use
non-ISO9899 libraries.

If you replace "programs" with "translation units" or "lines of code",
this is also consistent with my experience. Most of the code I write
does interesting things with data (which rarely if ever needs anything
beyond standard C) and interfaces with the rest of the world by using
system-specific code (which has already been written, often but not
always for every platform I'm interested in) to talk to something at
the other end of a network connection.

(It is, however, far from unheard of for the system-specific parts to
be moved out of the program and to the ends of a unix pipeline, leaving
a completely standard C program (or several) running offline or in the
middle of a network-server-in-a-line-of-shell-code, instead of linking
it with the code that's doing the interesting work.)


dave

[1] 'dual' is used here in its sense as a technical mathematical term
meaning approximately "describes the same thing from a different
perspective"
 
G

Gordon Burditt

On the other hand, I think that there was a call somewhere in this
thread for fileinformation() which I think might be a very nice
addition. I guess that even filesize() might not be so bad if they
renamed it currentfilesize(). Then (at least) it would be obvious
that it only contains an estimate.

No, it should be named previousfilesize(), since that's what it
returns.
 
R

Richard

Mark McIntyre said:
No. Suggest you read up on this.

Pedantic.

Reduced instruction sets lead to the dropping of many features which ate
up lots of clock cycles which were hardly ever used.

The main idea being to produce a small suite of very fast useful
instructions.

In addition, the reduction in complex instructions meant more room for
fast registers and resulting higher CPU operating speeds.

I suggest you read up on this.
 
C

CBFalconer

jacob said:
Look "CJ" whoever you are:

You know NOTHING of where I have programmed, or what I am doing.
Versions of lcc-win run in DSPs with 80k of memory, and only
20 usable.

Does that mean you have finally uncovered the reason it won't run
on a 486 under W98?
You (like all the "regulars") repeat the same lies about me again
and again but that doesn't makes them true.

Please specify some toasters or kettles controlled by lcc-win32.
Please also specify the breeds of CPU chips that are compatible.
You feel like insulting someone? Pick up another target or (much
better) try to stop kissing ass ok?

I saw no insult in CJs message. I did in yours.
 
E

Eric Sosman

Keith said:
Serve La said:
How about let filesize("/var/adm/messages") and others UB?? On some
systems it could return correct values on others an error

fflush(stdin) is UB so i dont see a reason why filesize should have
every single filetype perfectly defined.
And here in clc people will have 1 more reason to tell others that
demons will fly out of their nose when they try filesize() on
/dev/random or something!

Presumably filesize("/dev/random") could behave sensibly without
invoking undefined behavior. The system could detect that it's a
"character special file" and return an error indication. An
implementation of filesize() might fall back to reading every byte of
the file in some cases, but only when necessary. [...]

On all systems I know of that provide a "/dev/random"
file, reading all the bytes would take too long ...

(R.H.: Any update on the progress of your infinite
loop test?)
 
R

Richard Heathfield

Eric Sosman said:

(R.H.: Any update on the progress of your infinite
loop test?)

Alas, it seems that infinity is bigger than I at first realised. It would
be premature to give a percentage-completed report at this stage.
 
K

Kelsey Bjarnason

[snips]

There is no point in discussing with somebody that doesn't want
to go into the arguments of the other side. All multi user
OSes provide a "stat" function. This function gives of
course meaningless results and since at least 25 years progammers
use those "meaningless" results. Go figure, they did not know
"user923005" and the virtues of openvms.

P.S. by the way, in the reference I gave to the openvms wizard
there is a COBOL program to get the exact file size and other
attributes of the file. It wasn't anything very difficult as you say.

If you're going to change contexts - move the goalposts - don't be
surprised to find that the results don't match the problem.
 
K

Kelsey Bjarnason

[snips]

I am not surprised you say this either. Till now, there hasn't been
ANY system where there wasn't an operation to get the file size.
VAX/VMS included. And if there was one, it could ALWAYS do
1) Open the file
2) Read until EOF

to get the file size. Granted, it wouldn't be efficient in some weird
systems but so what? It would be possible.

But it would not necessarily be *meaningful* which you persist in
overlooking.

If you do this and calculate you need to allocate 17,403 bytes to read the
file, do you know that in the time it takes you to allocate the space,
rewind and commence reading, someone else has not changed the size of the
file?

In a single-user, single-tasking system, not a problem, presumably. In a
multi-user system where the file is shared between many users, it's
entirely possible your calculations aren't valid by the time you use them.

So, explain to us how this file size you've calculated means anything
relevant to the C code issues discussed here - notably, trying to read the
entire file into a buffer.
 
K

Kelsey Bjarnason

[snips]

We could restrict this to normal files.

What is a "normal" file?

There are file systems supporting sparse files, which in most cases appear
to be "normal" files, except that while they're reported to be of one
size, they're actually another size entirely - they claim to be 2GB, but
only occupy 200K on disk, for example.

Other systems allow for compressed or partially compressed files, where
the actual size of the data bears little, if any, relation to the size of
the file on disk.

And on and on and on.

What's needed, then, is not a way to calculate size on disk, but "size to
be read" - actual number of bytes to be processed by your code, after any
applicable decompression, translation, etc, etc, etc - and further, a way
to calculate this such that the results are valid despite the potential
for other users or processes to modify the file.

How, exactly, do you figure on accomplishing this, hmm?
 
G

Gordon Burditt

But it would not necessarily be *meaningful* which you persist in
overlooking.

A similar problem occurs for people wanting "how many people are
using this file" functions, intending to use them in place of file
locking.
If you do this and calculate you need to allocate 17,403 bytes to read the
file, do you know that in the time it takes you to allocate the space,
rewind and commence reading, someone else has not changed the size of the
file?

The size of the file can be changed before you have a chance to
even receive the result of the hypothetical filesize() function.
It doesn't have to be while you're doing a calculation with it.
In a single-user, single-tasking system, not a problem, presumably. In a

If the file in question is the file to which stdout of this program
is redirected, it could be a problem anyway. Consider something
like "DIR > log.txt" under MS-DOS. What size of the file log.txt
does it show? You can get the same problem with "ls -l > log.txt"
under UNIX, without needing two processes accessing the file
simultaneously.

You can also run into problems with commands like
"md5sum * > md5.checksums", which computes the MD5 checksum of a
bunch of files. What checksum is shown for the "md5.checksums"
file (which is included in the expanded wildcard).
multi-user system where the file is shared between many users, it's
entirely possible your calculations aren't valid by the time you use them.

It is also entirely possible that the file size has been changed
by someone with MALICIOUS INTENT. Someone who insists that the
file size can't change is likely to code in a way that causes a
buffer overflow when it does change size. This can lead to arbitrary
code execution, which sometimes leads to the computer becoming part
of a botnet. Take a look at patches issued by Microsoft for Windows
and related programs. Many of them are related to buffer overflows
by maliciously malformed data of some kind.
 
S

Serve Lau

Keith Thompson said:
A filesize() function, with all its limitations, *could* have been
included in the standard. It wasn't. If it had been, it might have
been useful in some contexts, but you'd have to be very careful in
using it. I suspect that a function that takes a FILE* would be more
useful than one that takes a file name; perhaps both could have been
provided.

Yes I think too that such a function could be standardized and where the
function doesnt make any sense it could return an error or be excluded.
I just gave the string argument as an example to get it all on one line ;)
I'd prefer a FILE * in the real interface too.
I have no strong opinion on whether a filesize() function *should*
have been in the C standard. The fact is that it isn't. The lack has
not been a serious problem, since the functionality is generally
available when needed. And adding it to the standard now would be a
long and slow process -- one that is not particularly helped (or hurt)
by talking about it here.

I agree, all systems I know where such a function could be useful have fstat
so its already possible to write portable code for your application domain.
No real need to standardize but it would be nice. I just found the
resistance to adding such a function in this thread strange
If you really want filesize() in the C standard, one way to start
making that happen is to write a proposal and post it to comp.std.c
for discussion.

Jacob seems to want it more judging by his use of capitals in his posts :p
 
G

Gordon Burditt

We could restrict this to normal files.
What is a "normal" file?

There are file systems supporting sparse files, which in most cases appear
to be "normal" files, except that while they're reported to be of one
size, they're actually another size entirely - they claim to be 2GB, but
only occupy 200K on disk, for example.

But they take 2GB to read into memory, if that is the number of interest.
Other systems allow for compressed or partially compressed files, where
the actual size of the data bears little, if any, relation to the size of
the file on disk.

But the uncompressed size is the relevant number for space to read it
into memory.
And on and on and on.

What's needed, then, is not a way to calculate size on disk, but "size to
be read" - actual number of bytes to be processed by your code, after any
applicable decompression, translation, etc, etc, etc - and further, a way
to calculate this such that the results are valid despite the potential
for other users or processes to modify the file.
How, exactly, do you figure on accomplishing this, hmm?

Mandatory file locking is one way to accomplish this, but it has
other problems. It opens the system up to denial-of-service attacks
by a program that locks lots of important system files to keep
administrators out, then proceeds to do something evil.
 
S

Serve Lau

So we've gone from having a non-portable way to do something that's
useful and meaningful on some systems, to having a non-portable way to
do something that's useful and meaningful on some systems.

Remind me again what the point of this exercise was?

Portable code which checks a file size can be written then but a programmer
cant just expect to do something strange like check the size of "LPT1" and
expect the standard C function to work correctly. In fact writing
fopen("LPT1:", "r"); is already not portable anymore in the sense that your
code wont work on multiple systems. Same goes for most of the other system
dependant files mentioned.
 
J

jacob navia

Kelsey said:
[snips]

I am not surprised you say this either. Till now, there hasn't been
ANY system where there wasn't an operation to get the file size.
VAX/VMS included. And if there was one, it could ALWAYS do
1) Open the file
2) Read until EOF

to get the file size. Granted, it wouldn't be efficient in some weird
systems but so what? It would be possible.

But it would not necessarily be *meaningful* which you persist in
overlooking.

If you do this and calculate you need to allocate 17,403 bytes to read the
file, do you know that in the time it takes you to allocate the space,
rewind and commence reading, someone else has not changed the size of the
file?

In a single-user, single-tasking system, not a problem, presumably. In a
multi-user system where the file is shared between many users, it's
entirely possible your calculations aren't valid by the time you use them.

So, explain to us how this file size you've calculated means anything
relevant to the C code issues discussed here - notably, trying to read the
entire file into a buffer.

Yes, this is 100% clear logic. I will apply it then.

1) You can't open a file with
fopen("name","a+")
since somebody else could grow the file after the file is positioned at
EOF, so you would overwrite his data.

2) ftell/fseek/ and in general all file primitives should be dropped
from the standard. If you write something somebody else could have
written at the same position. You should not write in a file.

Nice isn't it?

I have answered this thousand times but you still come back with the
same nonsense!
 
J

jacob navia

Serve said:
Portable code which checks a file size can be written then but a
programmer cant just expect to do something strange like check the size
of "LPT1" and expect the standard C function to work correctly. In fact
writing
fopen("LPT1:", "r"); is already not portable anymore in the sense that
your code wont work on multiple systems. Same goes for most of the other
system dependant files mentioned.

Yes. We should ban fopen/fwrite/ and all file primitives.

This has been answered thousand times but this people come back again
and again with the same nonsense.
 
S

Serve Lau

William Pursell said:
If you want to know what n is, then you check
it. Perhaps like so:

int main(void) {
int n = printf("hello\n");
printf(" n = %d\n", n );
return 0;}

*waiting for the regulars to point out the obvious flaw in this code*
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,227
Latest member
Daniella65

Latest Threads

Top