memcpy/memmove

  • Thread starter Christopher Benson-Manica
  • Start date
C

Christopher Benson-Manica

(if this is a FAQ or in K&R2, I didn't find it)

What parameters (if any) may be 0 or NULL? IOW, which of the following
statements are guaranteed to produce well-defined behavior?

char src[10];
char dst[10];

memcpy( dst, src, 1 );
memcpy( NULL, src, 1 );
memcpy( dst, src, 0 );
memcpy( NULL, src, 0 );
memcpy( dst, NULL, 1 );
memcpy( NULL, NULL, 1 );
memcpy( dst, NULL, 0 );
memcpy( NULL, NULL, 0 );
 
T

Thomas Matthews

Christopher said:
(if this is a FAQ or in K&R2, I didn't find it)

What parameters (if any) may be 0 or NULL? IOW, which of the following
statements are guaranteed to produce well-defined behavior?

char src[10];
char dst[10];

memcpy( dst, src, 1 );
memcpy( NULL, src, 1 );
memcpy( dst, src, 0 );
memcpy( NULL, src, 0 );
memcpy( dst, NULL, 1 );
memcpy( NULL, NULL, 1 );
memcpy( dst, NULL, 0 );
memcpy( NULL, NULL, 0 );

According to my research (I suggest you search the newsgroups),
any argument can be NULL. However, if the destination or
source are NULL or the quantity is null, nothing happens.


--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html
Other sites:
http://www.josuttis.com -- C++ STL Library book
 
S

Simon Biber

Christopher Benson-Manica said:
What parameters (if any) may be 0 or NULL? IOW, which of the
following statements are guaranteed to produce well-defined
behavior?

char src[10];
char dst[10];

memcpy( dst, src, 1 );

Defined behaviour: One byte is copied from src to dest.
memcpy( dst, src, 0 );

Defined behaviour: no characters are copied.
memcpy( NULL, src, 1 );
memcpy( NULL, src, 0 );
memcpy( dst, NULL, 1 );
memcpy( NULL, NULL, 1 );
memcpy( dst, NULL, 0 );
memcpy( NULL, NULL, 0 );

All six have undefined behaviour: both pointers must be valid
pointers even if the number of characters to copy is zero.

C99 7.21.1#2 "Where an argument declared as size_t n specifies
the length of the array for a function, n can have the value
zero on a call to that function. Unless explicitly stated
otherwise in the description of a particular function in this
subclause, pointer arguments on such a call shall still have
valid values, as described in 7.1.4. On such a call, a
function that locates a character finds no occurrence, a
function that compares two character sequences returns zero,
and a function that copies characters copies zero characters."
 
C

Christopher Benson-Manica

Simon Biber said:
All six have undefined behaviour: both pointers must be valid
pointers even if the number of characters to copy is zero.
C99 7.21.1#2 (trimmed)

Thank you. Now, if only K&R2, my other C book, or my friendly man page had
said as much...
 
I

Irrwahn Grausewitz

Thomas Matthews said:
Christopher said:
(if this is a FAQ or in K&R2, I didn't find it)

What parameters (if any) may be 0 or NULL? IOW, which of the following
statements are guaranteed to produce well-defined behavior?

char src[10];
char dst[10];

memcpy( dst, src, 1 );
memcpy( NULL, src, 1 );
memcpy( dst, src, 0 );
memcpy( NULL, src, 0 );
memcpy( dst, NULL, 1 );
memcpy( NULL, NULL, 1 );
memcpy( dst, NULL, 0 );
memcpy( NULL, NULL, 0 );

According to my research (I suggest you search the newsgroups),
any argument can be NULL.

Not so. I suggest you search the Standard. ;-)

Regards
 
D

Dan Pop

In said:
That's where a copy of the Standard comes in handy.

Not so. It is enough to engage your brain. The only non-obvious cases
are those where the byte count is 0: because no byte gets copied, it is
not obvious if null pointers are allowed. OTOH, these are purely
artificial cases, with no relevance in practice. Even C90 didn't
cover them, it was its TC1 that addressed the issue.

Dan
 
I

Irrwahn Grausewitz

Not so. It is enough to engage your brain. The only non-obvious cases
are those where the byte count is 0: because no byte gets copied, it is
not obvious if null pointers are allowed.

And how should one know about this facts from only engaging one's
brain? We're not all Dan Pops, y'know... ;-)
OTOH, these are purely
artificial cases, with no relevance in practice.

Sorry, I have to disagree. The memcpy function et al. might well have
been designed to accept NULL arguments (resulting in a no-op), for the
very same reason that free(NULL); is well-defined.
Even C90 didn't
cover them, it was its TC1 that addressed the issue.

And there was a reason for it, I suspect.

Regards
 
A

Alex

Irrwahn Grausewitz said:
(e-mail address removed) (Dan Pop) wrote:

And how should one know about this facts from only engaging one's
brain? We're not all Dan Pops, y'know... ;-)
Sorry, I have to disagree. The memcpy function et al. might well have
been designed to accept NULL arguments (resulting in a no-op), for the
very same reason that free(NULL); is well-defined.

free(NULL) is an exception. It is really nothing more than a pragmatic
hack.

What possible behavior can you expect from copying 1 or more bytes
from or to NULL?

Dan is right, the only vagueness is in the case of the count being 0,
hence making it seem plausible that copying 0 bytes from NULL or to
NULL is allowed. Even then, can you think of a case where this would
be desirable?

Alex
 
I

Irrwahn Grausewitz

Alex said:
free(NULL) is an exception. It is really nothing more than a pragmatic
hack.

What possible behavior can you expect from copying 1 or more bytes
from or to NULL?

As stated above: a no-op, like free(NULL), the rationale behind it
being to reduce the need for special-case coding.
Dan is right, the only vagueness is in the case of the count being 0,
hence making it seem plausible that copying 0 bytes from NULL or to
NULL is allowed. Even then, can you think of a case where this would
be desirable?

I'm not even sure I could come up with a good example where copying
0 bytes is very useful. But still: the standard committee /could/
have defined the behaviour for the first or second parameter of memcpy
set to NULL just as it did for the third parameter set to 0. Without
having read the corresponding section in the standard nobody can tell
what is defined and what not, just "by engaging one's brain" as Dan
said, which was the point I tried to make.

Regards
 
S

Simon Biber

Irrwahn Grausewitz said:
As stated above: a no-op, like free(NULL), the rationale behind it
being to reduce the need for special-case coding.

It just moves the special case coding from the user code into the
library function.

Some library functions, like free, are quite complicated and slow
to execute, so an added test for NULL won't make much difference.
However, some library functions might suffer significantly in
speed or complexity if they had to be resilient to invalid input.
 
C

Christian Bau

Alex said:
free(NULL) is an exception. It is really nothing more than a pragmatic
hack.

What possible behavior can you expect from copying 1 or more bytes
from or to NULL?

Lets say I design a brand new language named "D", which has a standard
library and standard library functions that have the same names and
arguments as those in C. The definition of the semantics of these
functions is done in the way that _I_ prefer and which _I_ think is
useful.

How would you know without careful reading of the "D" standard what the
behavior of memcpy (NULL, src, 1) is? In C, it is likely to cause a
crash. I can imagine a lot more useful behaviors.
 
I

Irrwahn Grausewitz

Simon Biber said:
It just moves the special case coding from the user code into the
library function.

Obviously.
Some library functions, like free, are quite complicated and slow
to execute, so an added test for NULL won't make much difference.
However, some library functions might suffer significantly in
speed or complexity if they had to be resilient to invalid input.

True, but nevertheless, they /could/ be designed that way. And still,
reasoning cannot always replace a look in the standard or a good
library reference (unless you are Dan Pop, of course ;-)), especially
when you are a novice. Which was the only point I wanted to make,
anyway.

Regards
 
C

Christopher Benson-Manica

Irrwahn Grausewitz said:
True, but nevertheless, they /could/ be designed that way. And still,
reasoning cannot always replace a look in the standard or a good
library reference (unless you are Dan Pop, of course ;-)), especially
when you are a novice. Which was the only point I wanted to make,
anyway.

Which I do appreciate :) I didn't necessarily *expect* any but the first two
cases to be 100% legal, but since no reference I had access to specified what
to expect, I had to ask...
 
D

Dan Pop

In said:
Lets say I design a brand new language named "D", which has a standard
library and standard library functions that have the same names and
arguments as those in C. The definition of the semantics of these
functions is done in the way that _I_ prefer and which _I_ think is
useful.

How would you know without careful reading of the "D" standard what the
behavior of memcpy (NULL, src, 1) is?

The good question is why would you care about the exact behaviour of
memcpy(NULL, src, 1)? Does such a call make any sense?
In C, it is likely to cause a
crash. I can imagine a lot more useful behaviors.

I cannot. If you do this, there is something broken in the logic of your
program. Not letting it continue its execution is a big favour to both
the developer and the user. Too bad C does not *enforce* this behaviour.

Dan
 
C

Christian Bau

[email protected] (Dan Pop) said:
In <[email protected]> Christian


The good question is why would you care about the exact behaviour of
memcpy(NULL, src, 1)? Does such a call make any sense?

It would be good to know what happens when the programmer writes a
function call that doesn't make sense.
I cannot. If you do this, there is something broken in the logic of your
program. Not letting it continue its execution is a big favour to both
the developer and the user. Too bad C does not *enforce* this behaviour.

Here is a more useful behavior than crashing: An alert pops up on the
screen, saying "this program tried to do something nasty. The code is in
file xxx, line yyy. Press Continue to continue the program without doing
the action. Press Quit to exit the program. ".

Consider Java-like behavior: An exception is thrown, which gives the
programmer a chance to handle the situation. Much more useful than
crashing.
 
D

Dan Pop

In said:
It would be good to know what happens when the programmer writes a
function call that doesn't make sense.

What for? The C standard doesn't say what happens and this has never
been a problem for me, in practice.
Here is a more useful behavior than crashing: An alert pops up on the
screen, saying "this program tried to do something nasty. The code is in
file xxx, line yyy. Press Continue to continue the program without doing
the action. Press Quit to exit the program. ".

How is this helpful in any way to the *user*? Does he have to toss a
coin to decide whether to press Continue or Quit?

How is it helpful to the programmer, without having access to the
program state, so that he can trace the origin of the problem?

Crashing the program, the Unix way, is by far more helpful: not only can
you trivially get the file and line information, you have also access to
the program state at the moment the nasty thing happened.
Consider Java-like behavior: An exception is thrown, which gives the
programmer a chance to handle the situation. Much more useful than
crashing.

Crashing has always given me not only a chance, but the best opportunity
to investigate the problem and quickly discover its origin.

Dan
 
A

Alan Balmer

Here is a more useful behavior than crashing: An alert pops up on the
screen, saying "this program tried to do something nasty. The code is in
file xxx, line yyy. Press Continue to continue the program without doing
the action. Press Quit to exit the program. ".

Assuming there is a screen, assuming the implementation supports
"pop-up" alerts, assuming the program always runs attended, assuming
there's an input capability, assuming ...

No. If the parameters can potentially be NULL, check them before the
call.
 
C

Christian Bau

Alan Balmer said:
Assuming there is a screen, assuming the implementation supports
"pop-up" alerts, assuming the program always runs attended, assuming
there's an input capability, assuming ...

Plenty of implementations where all these are available (running
attended is no requirement).
No. If the parameters can potentially be NULL, check them before the
call.

You mean people should just write bug-free code? Yes, that's a very
simple solution to all problems. No buffer overruns anymore, just write
bug-free code.
 
A

Alan Balmer

Plenty of implementations where all these are available (running
attended is no requirement).

Unfortunately for your suggestion, standard C is also expected to work
on the implementations where one or more of these features are not
available.

If the program is unattended, who's going to push the "Continue" and
"Quit" buttons?
You mean people should just write bug-free code? Yes, that's a very
simple solution to all problems. No buffer overruns anymore, just write
bug-free code.

That's at least as realistic a goal as providing a language and
implementation which will detect all possible programmer errors.
 

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

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top