size_t problems

P

pete

Richard said:
int aone[10];
int *const atwo = &aone[3];
(&aone[3]) is the address of an object of type int.

I realise this is just pedantry, but who can complain?

Is the following legal:

typedef int array_type[7];
array_type *atwo = (array_type *)&aone[3];[/QUOTE]

It depends on the alignment requirements of array_type.

N869
6.3.2.3 Pointers
[#7] A pointer to an object or incomplete type may be
converted to a pointer to a different object or incomplete
type. If the resulting pointer is not correctly aligned
for the pointed-to type, the behavior is undefined.
 
C

CBFalconer

jacob said:
.... snip ...

Standard C doesn't have

1) Any serious i/o. To do anything fast you need system specific
stuff.
2) Any notion of the keyboard. To handle the keyboard you need
system specific stuff.
3) Any graphics. Ditto.
4) No network.
5) Not any timers with reasonable accuracy.

C is very popular for systems programming but none of those programs
is written in standard C.

Utter rubbish. Most good systems programs are written in as
standard a form as is available of their language. Some may have a
system specific GUI add-on. Some (such as an IDE) may be a
combination of several standard programs with GUI interface. Some
(such as an editor) may require special keyboard input (system
specific).

.... snip ...
All this people talking about "Portable standard C" are just talking
nonsense. Or they do not use the network, nor do they do any
graphics, nor do they use any i/o, etc etc.

Yes, for toy applications it is barely portable, but even this program:

#include <stdio.h>
int main(void){printf("hello\n");}

is portable since the errors of printf are NOT specified, so you
have no way to know what happened if printf returns a negative
result, besides going into implementation specific stuff!

Purely because the writer was too lazy to write the program
'correctly'. As shown it contains at least two serious errors -
failure to return status, and failure to test the result from
printf. From N869:

[#14] The fprintf function returns the number of characters
transmitted, or a negative value if an output or encoding
error occurred.

A correct version could be:

#include <stdio.h>
#include <stdlib.h>
int main(void) {
if (0 > printf("hello\n")) return EXIT_FAILURE;
return 0;
}

BTW, systems have various possibilities of returning details on
printf errors, such as ferror and perror. See the standard. There
is a value known as QOI attached to most implementations.
 
C

CBFalconer

Joe said:
.... snip ...

I suppose you don't like '#define strlen Strlen'. It has the effect
of removing a reference to a standard library function and replacing
it with the name of a local function before compilation. Harmless.

Possibly so on your present system. However, according to the C
standard, any such redefinition of standard library facilities
leads to undefined behaviour. Note that that behaviour may be
exactly what you want and expected. It doesn't have to be such.
 
C

CBFalconer

Ed said:
.... snip ...

And while we're on the topic, I'd like to present a little poll:
Is there anyone else here that agrees with Martin when he says
that writing 100% portable C code is VERY easy? Keep in mind the
question isn't whether or not it's possible or desirable, just
whether or not it's VERY easy.

It all depends on the mindset. If you've been writing portable
code, you have the habit, and the unusual thing is non-portable
code. And the inverse also applies, and unfortunately is the more
common situation.
 
R

Richard Heathfield

Ed Jensen said:
Don't worry about it, Martin. To be honest, I was expecting that kind
of response much sooner. It's just sort of the...personality...of
this newsgroup. Since I've been online since about 1979, I've had
ample time to marvel at this kind of fascinating emergent behavior in
online communities.

There are very few regulars here in comp.lang.c that'll admit that
writing 100% portable C code is non-trivial.

I'm one of them, however.

I think it's easy to write *very* portable code, but difficult to write
100% portable code. Consider, for example, this simple program:

#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

int main(int argc, char **argv)
{
int rc = EXIT_SUCCESS;
unsigned long fa[UCHAR_MAX + 1] = {0};
int ch = 0;
size_t i = 0;
FILE *fp = argc > 1 ? fopen(argv[1], "rb") : NULL;
if(fp != NULL)
{
while((ch = getc(fp)) != EOF)
{
++fa[ch];
}
fclose(fp);
if(ferror(fp))
{
fputs("Input error.\n", stderr);
rc = EXIT_FAILURE;
}
else
{
for(i = 0; i < sizeof fa / sizeof fa[0]; i++)
{
if(fa > 0)
{
printf("%lu: %lu\n", (unsigned long)i, fa);
}
}
}
}
else
{
fputs("Can't open input file.\n", stderr);
rc = EXIT_FAILURE;
}
return rc;
}

This will work (I have tested it, so I know that it will at least
compile!) on Linux. It will work on Windows. With appropriate JCL,
it'll work on a mainframe. It will work on an Atari ST or an Amiga.
It'll work on MS-DOS. I see no reason why it wouldn't work on a Cray.
It'll work on lots of platforms, in fact.

It'll even work on a Mac - or will it? If not, why not?

And on what other platforms will it not work? And for what reasons? The
code /looks/ portable - but there are more problems in the code than
are immediately obvious to the eye.

I can see - well, several, at any rate! :)

And while we're on the topic, I'd like to present a little poll: Is
there anyone else here that agrees with Martin when he says that
writing 100% portable C code is VERY easy? Keep in mind the question
isn't whether or not it's possible or desirable, just whether or not
it's VERY easy.

It depends on the code. It's often possible but not always. It's always
desirable, but not necessarily the most significant requirement. *Some*
code is indeed very easy to write portably.
 
H

Harald van =?UTF-8?B?RMSzaw==?=

Richard said:
Ed Jensen said:
Don't worry about it, Martin. To be honest, I was expecting that kind
of response much sooner. It's just sort of the...personality...of
this newsgroup. Since I've been online since about 1979, I've had
ample time to marvel at this kind of fascinating emergent behavior in
online communities.

There are very few regulars here in comp.lang.c that'll admit that
writing 100% portable C code is non-trivial.

I'm one of them, however.

I think it's easy to write *very* portable code, but difficult to write
100% portable code. Consider, for example, this simple program:

#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

int main(int argc, char **argv)
{
int rc = EXIT_SUCCESS;
unsigned long fa[UCHAR_MAX + 1] = {0};
int ch = 0;
size_t i = 0;
FILE *fp = argc > 1 ? fopen(argv[1], "rb") : NULL;
if(fp != NULL)
{
while((ch = getc(fp)) != EOF)
{
++fa[ch];
}
fclose(fp);
if(ferror(fp))
{
fputs("Input error.\n", stderr);
rc = EXIT_FAILURE;
}
else
{
for(i = 0; i < sizeof fa / sizeof fa[0]; i++)
{
if(fa > 0)
{
printf("%lu: %lu\n", (unsigned long)i, fa);
}
}
}
}
else
{
fputs("Can't open input file.\n", stderr);
rc = EXIT_FAILURE;
}
return rc;
}

This will work (I have tested it, so I know that it will at least
compile!) on Linux. It will work on Windows. With appropriate JCL,
it'll work on a mainframe. It will work on an Atari ST or an Amiga.
It'll work on MS-DOS. I see no reason why it wouldn't work on a Cray.
It'll work on lots of platforms, in fact.

It'll even work on a Mac - or will it? If not, why not?

And on what other platforms will it not work? And for what reasons? The
code /looks/ portable - but there are more problems in the code than
are immediately obvious to the eye.

I can see - well, several, at any rate! :)


I can see one very obvious one: you're using a file after closing it. That's
not the way you should be writing code even if it's not meant to be
portable.

I can see one more potential problem, but it doesn't explain why you think
it might not work on a Mac. Could you give a hint?
 
R

Richard Heathfield

Harald van D?k said:
Richard Heathfield wrote:


I can see one very obvious one: you're using a file after closing it.
That's not the way you should be writing code even if it's not meant
to be portable.

Oh, stupid stupid stupid (me, not you). You're right, of course. That
was unintentional, by the way!
I can see one more potential problem, but it doesn't explain why you
think it might not work on a Mac. Could you give a hint?

I've never owned a Mac, nor executed my own code on own, so I'm going on
rumour and supposition, but it is my understanding that, on at least
*some* Mac implementations, argc is always 0, so the program will run,
but with unsatisfactory results.
 
J

jacob navia

CBFalconer said:
jacob navia wrote:
... snip ...

Utter rubbish. Most good systems programs are written in as
standard a form as is available of their language. Some may have a
system specific GUI add-on. Some (such as an IDE) may be a
combination of several standard programs with GUI interface. Some
(such as an editor) may require special keyboard input (system
specific).

... snip ...

Purely because the writer was too lazy to write the program
'correctly'. As shown it contains at least two serious errors -
failure to return status,

As specified in the C standard, main returns zero, and it is not
necessary to write a return statement.

Before you start talking nonsense read the standard.


and failure to test the result from
printf. From N869:

[#14] The fprintf function returns the number of characters
transmitted, or a negative value if an output or encoding
error occurred.

A correct version could be:

#include <stdio.h>
#include <stdlib.h>
int main(void) {
if (0 > printf("hello\n")) return EXIT_FAILURE;
return 0;
}


Ifyou re read your code you will see that you missed the ELSE arm of the
IF statement. You see?

That was precisely my point. How do you know what happened?
What error? You have to be system specific!

jacob
 
M

Mark McIntyre

Oh it's C all right, it just uses system specific libraries.

Pardon me, I should have said "in standard C, the topic of this
newsgroup"
Calling system specific functions does not prevent code from being C.

Some would disagree.
--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
 
M

Malcolm McLean

Ian Collins said:
There's nothing "not C" about "unsigned s = read( buffer, size);" for a
given definition of read.

Calling system specific functions does not prevent code from being C.
No, but we don't know what the code does.
read is almost certainly reading bytes into buffer. However it might also
clobber the stack and set size to zero, disallowed for a standard function.
There might be some reason this is desired and useful behaviour.
 
M

Mark McIntyre

There are very few regulars here in comp.lang.c that'll admit that
writing 100% portable C code is non-trivial.

So what? Writing portable C code /is/ straightforward. If you can be
bothered.

However I suspect you're being just as religious as those you're
attacking, and this isn't about being right, is it?
Therefore, I knew before I walked down this path, that the response
would ultimately be, "The problem can't possibly be that it's
non-trivial to write 100% portable C code; the problem must be you."

Unsurprisingly, with the attitude your post shows.
And while we're on the topic, I'd like to present a little poll: Is
there anyone else here that agrees with Martin when he says that
writing 100% portable C code is VERY easy?

The question is meaningless without context.

Writing a fully portable programme to manipulate the contents of a
file is no harder than writing a nonportable programme to do the same.
Indeed it may be /harder/ to write a nonportable programme. Whether
either is /very easy/ depends on what you're trying to do with the
data.

Writing a portable programme to manipulate the robotic arm of the
space shuttle is likely to be impossible on the other hand, as
standard, portable C knows nothing about stepping motor controls.

--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
 
M

Malcolm McLean

Harald van D?k said:
Richard Heathfield wrote:

I can see one more potential problem, but it doesn't explain why you think
it might not work on a Mac. Could you give a hint?
The Mac supports every character knwon to man.
So UCHAR_MAX is 0xFFFFFFFFFFFFFFFF
64 bits for everything. That's what I like to see. OK maybe the Mac can't
reach such heights just yet, but Steve Jobs has just emailed me with an
order for a "give me 64" T-shirt, so it will soon.
Perfectly permitted by the standard. And of course the compiler doesn't
check for stack overflow.
 
M

Mark McIntyre

As specified in the C standard, main returns zero, and it is not
necessary to write a return statement.

True in C99, but not in the widely-implemented and still widely used
C89. Compilers conforming to that standard will emit garbage and can
(and do) upset their host environments.

--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
 
I

Ian Collins

Malcolm said:
No, but we don't know what the code does.
read is almost certainly reading bytes into buffer. However it might
also clobber the stack and set size to zero, disallowed for a standard
function. There might be some reason this is desired and useful behaviour.

#include <stddef.h>

extern size_t read( void*, size_t );

int main(void) {
char buf[10];
size_t n = read( buf, 10 );
return 0;
}

Standard C or not standard C?
 
J

jacob navia

Martin said:
CBFalconer:



Just as an example, the strlen on Microsoft Windows compilers test
entire 4-byte chunks at a time looking for a byte which is all zeros.
It's a hell of a lot faster than using a canonical loop.

Martin

To do that, it has to find an address multiple of four.
Since strings aren't naturally aligned (they could start at
ANY address) it has to make a few comparisons before finding the
right starting address. This means more setup time.

For strings with length less than 80-100 this, together with the
function call, will kill any performance improvements.

When using the optimizer, lcc-win32 generates an inline loop
of 4-5 assembler instructions, comparing character by
character. For relatively short strings, this will beat
any strlen function since the overhead of the function call
is much greater...
 
J

jacob navia

Ed Jensen wrote
> There are very few regulars here in comp.lang.c that'll admit that
> writing 100% portable C code is non-trivial.

Then,Richard Heathfield answered:
> I'm one of them, however.
> I think it's easy to write *very* portable code, but difficult to write
> 100% portable code. Consider, for example, this simple program:

[code snipped]

Harald van Dijk answered:
And heathfield had to acknowledge...
Oh, stupid stupid stupid (me, not you). You're right, of course. That
was unintentional, by the way!


Ahh the "regulars" here. Always the pompous claims but then, they
present a few lines of code with such an OBVIOUS bug!


jacob
 
K

Keith Thompson

jacob navia said:
To do that, it has to find an address multiple of four.
Since strings aren't naturally aligned (they could start at
ANY address) it has to make a few comparisons before finding the
right starting address. This means more setup time.

For strings with length less than 80-100 this, together with the
function call, will kill any performance improvements.

When using the optimizer, lcc-win32 generates an inline loop
of 4-5 assembler instructions, comparing character by
character. For relatively short strings, this will beat
any strlen function since the overhead of the function call
is much greater...

There's no reason it couldn't do exactly the same thing for an
explicit call to strlen().
 
H

Harald van =?UTF-8?B?RMSzaw==?=

Malcolm said:
The Mac supports every character knwon to man.
So UCHAR_MAX is 0xFFFFFFFFFFFFFFFF

No, that's not the case on Macs, and while I realise there are some real
systems that have a 64-bit char, it is my understanding that they are
freestanding implementations which do not use the standard I/O functions.
(I would appreciate details on implementations with 64-bit char and
<stdio.h>, though.)
 
K

Keith Thompson

jacob navia said:
Ed Jensen wrote
There are very few regulars here in comp.lang.c that'll admit that
writing 100% portable C code is non-trivial.

Then,Richard Heathfield answered:
I'm one of them, however.
I think it's easy to write *very* portable code, but difficult to write
100% portable code. Consider, for example, this simple program:

[code snipped]

Harald van Dijk answered:
And heathfield had to acknowledge...
Oh, stupid stupid stupid (me, not you). You're right, of
course. That was unintentional, by the way!


Ahh the "regulars" here. Always the pompous claims but then, they
present a few lines of code with such an OBVIOUS bug!

Everyone makes mistakes.

The "regulars", in my experience, are distiguished by their
willingness to acknowledge and correct their mistakes, and to thank
those who point them out.

Incidentally, you recently claimed that "C Unleashed" contains some
code that assumes sizeof(int) == sizeof(int*). Can you be more
specific? I'm sure the authors would like to know about it. I think
Richard Heathfield has you killfiled; if you'll post the specifics,
I'll re-post for his benefit.
 
H

Harald van =?UTF-8?B?RMSzaw==?=

Richard said:
Harald van D?k said:

I've never owned a Mac, nor executed my own code on own, so I'm going on
rumour and supposition, but it is my understanding that, on at least
*some* Mac implementations, argc is always 0, so the program will run,
but with unsatisfactory results.

Oh, thanks for the explanation. That's not the case with OS X, though it may
well be true for some of the implementations for older systems.
 

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

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,240
Members
46,829
Latest member
KimberAlli

Latest Threads

Top