473,432 Members | 1,780 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,432 software developers and data experts.

strndup: RFC

Hi
Reading comp.std.c I noticed that there was a message like this:
The WG14 Post Portland mailing is now available from the WG14 web site
at http://www.open-std.org/jtc1/sc22/wg14/

Best regards
Keld Simonsen

I went there and found that there is a report called
ISO/IEC JTC1 SC22 WG14 WG14/N1193
Specification for Safer C Library Functions —
Part II: Dynamic Allocation Functions

It proposes really interesting functions, among others getline and
getdelim, that I introduced into lcc-win32 (by coincidence) a few weeks
ago.

It proposes strdup and strndup too. Lcc-win32 proposes already strdup,
but strndup was missing. Here is a proposed implementation. I would like
to see if your sharp eyes see any bug or serious problem with it.

Thanks in advance

jacob
---------------------------------------------------------cut here
#include <string.h>
#include <stdlib.h>
/*
The strndup function copies not more than n characters (characters that
follow a null character are not copied) from string to a dynamically
allocated buffer. The copied string shall always be null terminated.
*/
char *strndup(const char *string,size_t s)
{
char *p,*r;
if (string == NULL)
return NULL;
p = string;
while (s 0) {
if (*p == 0)
break;
p++;
s--;
}
s = (p - string);
r = malloc(1+s);
if (r) {
strncpy(r,string,s);
r[s] = 0;
}
return r;
}

#ifdef TEST
#include <stdio.h>
#define MAXTEST 60
int main(void)
{
char *table[MAXTEST];
char *str = "The quick brown fox jumps over the lazy dog";

for (int i=0; i<MAXTEST;i++) {
table[i] = strndup(str,i);
}
for (int i=0; i<MAXTEST;i++) {
printf("[%4d] %s\n",i,table[i]);
}
return 0;
}
#endif
Dec 2 '06
68 6983
Richard Heathfield <rj*@see.sig.invalidwrites:
st*****@yahoo.com said:
>Richard Heathfield wrote:
[...]
>>Except that neither EINVAL nor ENOMEM is defined by the Standard.

Ah, another glaring deficiency of the standard. Every implementation I
have used for over 20 years has had EINVAL and ENOMEM defined.

I don't see why that means the Standard is deficient. By the same reasoning,
someone who has only ever used Turbo C 2.0 could claim that the Standard is
glaringly deficient in its omission of initgraph() from the library section
despite its being present in every implementation that person has used for
over 20 years - but this would not say so much about the Standard as it
would about the person making the claim!
Yes, but EINVAL ("Invalid argument") and ENOMEM ("Not enough space")
are much more generic, perhaps to the point of being universal, than
something like initgraph().

The only E* macros defined by the standard in <errno.hare EDOM,
EILSEQ, and ERANGE. I don't see the lack of EINVAL and ENOMEM as
"glaring deficiencies", but it would have been perfectly reasonable to
include them.

On the other hand, standardizing more E* macros would encourage the
use of the ugly errno mechanism. On the other other hand, it would be
nice if the standard offered something better. On the other**3 hand,
defining a decent error handling mechanism for C without turning it
into C++ would be non-trivial.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Dec 4 '06 #51
Richard Heathfield wrote:
jacob navia said:

<snip>
>>Since there isn't in C a portable way to determine if a memory
block is the result of malloc() we are screwed...


There is actually such a way. It's called "programming". When we call
malloc, obviously we know we're calling malloc, so we're in an ideal
position to record the fact that this particular pointer was returned by
malloc. The fact that there isn't some magical "is_malloc" function in ISO
C doesn't mean that there is no portable way to achieve what we want.

It's the same as with block sizes - "if you need to know this, well, at one
point in the program you *do* know it, so the answer is simply: DON'T
FORGET".
Please....

You really mean that for users to use this getline()
function they should set up a complicated system of maintaining a list
of memory allocated with their sizes???

Dec 4 '06 #52
jacob navia said:
Richard Heathfield wrote:
>jacob navia said:

<snip>
>>>Since there isn't in C a portable way to determine if a memory
block is the result of malloc() we are screwed...


There is actually such a way. It's called "programming". When we call
malloc, obviously we know we're calling malloc, so we're in an ideal
position to record the fact that this particular pointer was returned by
malloc. The fact that there isn't some magical "is_malloc" function in
ISO C doesn't mean that there is no portable way to achieve what we want.

It's the same as with block sizes - "if you need to know this, well, at
one point in the program you *do* know it, so the answer is simply: DON'T
FORGET".

Please....

You really mean that for users to use this getline()
function they should set up a complicated system of maintaining a list
of memory allocated with their sizes???
No, I only mean that it is possible for a program to keep track of such
things and, if it is *necessary*, then of course it should be done. If
getline() makes memory management too much of a pain for a particular task,
well, there is no shortage of alternatives.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Dec 4 '06 #53
jacob navia <ja***@jacob.remcomp.frwrote:
Roland Pibinger a écrit :
On Sat, 02 Dec 2006 23:53:26 +0100, jacob navia wrote:
>It proposes really interesting functions, among others getline and
getdelim, that I introduced into lcc-win32 (by coincidence) a few weeks
ago.
It proposes strdup and strndup too. Lcc-win32 proposes already strdup,
but strndup was missing.
strdup, getline and other functions require deallocation by the user.
They were deliberately excluded from the C Standards. Not by
oversight, not because they were difficult to implement, not because
they wouldn't have been 'useful'.
Actually, TTBOMK they were not included for three reasons:
- There was not enough prior art for them back then, as explained in the
Rationale;
- There would have to be an argument about whether they belonged in
<string.h>, because they deal with strings, or in <stdlib.h>, because
they deal with memory allocation, and no matter which of those were
chosen, there would always have been accusations of the Committee
getting it horribly wrong (because this is precisely the kind of anal-
retentive detail about which some people who should get a hobby Have
Opinions);
- They are remarkably simple for the user-programmer to write.
1) What's wrong with the user deallocating?
For a programmer with more than a year's experience, nothing.
2) Maybe this view is changing since that technical report is there...
That TR looks like a follow-up on that other "safer" function report.
It, too, was broken.

Richard
Dec 5 '06 #54
rp*****@yahoo.com (Roland Pibinger) wrote:
On Sun, 03 Dec 2006 10:01:01 -0500, CBFalconer wrote:
Not to mention fopen.

Wrong analogy again. Would you write a function like the following
(probably not):

/* user must call fclose() on the returned FILE* */
FILE *do_something (int i);
Yes, I would definitely write a function like that. It is very useful
for, say, opening a log file and writing a standardised header to it.
The calling function(s) then write log entries to it, and close it when
it's no longer needed.

Richard
Dec 5 '06 #55
In article <45**************@news.utanet.at>,
Roland Pibinger <rp*****@yahoo.comwrote:
>>By that reasoning malloc, calloc, and realloc should also be
omitted.
>Why? Do those functions force you to free something you haven't
allocated?
Um, why do you consider that you have done the allocating in the
case of calloc() but not in the case of strdup()? Both allocate
some memory and store values in it.
>Would you write a function like the following
(probably not):

/* user must call fclose() on the returned FILE* */
FILE *do_something (int i);
Whyever not?

-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Dec 5 '06 #56
"Roland Pibinger" <rp*****@yahoo.comwrote in message
news:45***************@news.utanet.at...
On Sun, 3 Dec 2006 14:02:54 -0600, "Stephen Sprunk" wrote:
>>I've written code like that, yes, though more often with <OT>open() /
close()</OTthan fopen() / fclose(). It's also pretty standard when
working with <OT>sockets</OT>; because they require so much
f'ing work to create, people tend to put all that in another function
to
avoid clutter.

IMO, there is no problem when you write your own symmetric open
(create, connect, ...) and close (cleanup, disconnect, ...) functions,
e.g.

Handle h = my_open (...);
// ...
my_close (h);
Except that, in the case of <OT>sockets</OT>, all you need is a simple
close(fd) to get rid of them. I suppose I could create a my_close(fd)
function, but in reality all it'd do is close(fd), and people would end
up not using it because it'd add overhead.
>>This whole "who deallocates the returned string" argument is one of
the
largest problems I have with C; yes, you can always find the correct
answer if you look at the function specs (assuming they exist), but
it's
not obvious and is therefore prone to errors.

So just don't do it, i.e. don't return a string that has to be freed
by the caller. Even the Windows API uses that convention, AFAIK.
.... and the result is that any time you call a huge number of
<OT>Windows API</OTfunctions, you have to call them twice: once with a
NULL argument to find out how big of a buffer to create, and again after
you've created the buffer to actually get the data you wanted. That's
not so great an idea when you consider the overhead of having to do all
your syscalls twice, and it leads to people taking shortcuts that end up
biting them later.

S

--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking
--
Posted via a free Usenet account from http://www.teranews.com

Dec 5 '06 #57
rl*@hoekstra-uitgeverij.nl (Richard Bos) writes:
rp*****@yahoo.com (Roland Pibinger) wrote:
>On Sun, 03 Dec 2006 10:01:01 -0500, CBFalconer wrote:
>Not to mention fopen.

Wrong analogy again. Would you write a function like the following
(probably not):

/* user must call fclose() on the returned FILE* */
FILE *do_something (int i);

Yes, I would definitely write a function like that. It is very useful
for, say, opening a log file and writing a standardised header to it.
The calling function(s) then write log entries to it, and close it when
it's no longer needed.
That's a good example. In effect, the function is a wrapper around
fopen(). If you absolutely insist on having strict pairings of
functions for allocation and deallocation, you could write
FILE *open_log(int i);
int close_log(FILE *log);
but close_log would do exactly the same thing as fclose().

In general, some functions allocate resources, and other functions
deallocate those same resources. Having a strict one-to-one mapping
between the two can be helpful, I suppose, but IMHO it's not strictly
necessary. Even the standard memory allocation functions don't do
this; malloc() and calloc() both allocate memory, free() deallocates
it, and realloc() potentially does both. The clean symmetry of
fopen() and fclose() is broken by freopen().

Programmers simply have to *read the documentation* to find out which
function does what. The interface described by the documentation
should be as simple as possible, but no simpler. If it makes sense to
have a strict pairing of allocators and deallocators, by all means do
that; if it doesn't, don't.

(In OO terms, there's no requirement to have exactly one constructor
and exactly one destructor for a given type.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Dec 5 '06 #58
Richard Heathfield wrote:
st*****@yahoo.com said:
>Richard Heathfield wrote:
>>Stan Milam said:

<snip>
Why can't you test the arguments for valid conditions and set errno to
EINVAL when one of the condition fails, and return NULL. Now, if the
validations are good and the memory allocation fails errno will be set
to ENOMEM. Now you know why you failed and can get the error message
with strerror().
Except that neither EINVAL nor ENOMEM is defined by the Standard.
Ah, another glaring deficiency of the standard. Every implementation I
have used for over 20 years has had EINVAL and ENOMEM defined.

I don't see why that means the Standard is deficient. By the same reasoning,
someone who has only ever used Turbo C 2.0 could claim that the Standard is
glaringly deficient in its omission of initgraph() from the library section
despite its being present in every implementation that person has used for
over 20 years - but this would not say so much about the Standard as it
would about the person making the claim!
I haven't used Turbo C since around 1992. I never cared for it either.
I've used C on several platforms, mostly UNIX these past few years,
but also DOS and some embedded stuff, using a wide variety of compilers.
EINVAL and ENOMEM have always been defined so why not standardize
them? Now as for the initgraph() analogy (this shows you know more
about Turbo C than I do), well, that is just silly. Of course a
compiler vendor's graphic library is not very likely to be portable,
ergo not a good candidate for standardization, but every C program I
know has functions using arguments, and dynamic memory allocation is a
way of life in C (and one of the truly great things about C). Why not
define values for errno when invalid argument values are used and when
no memory is available for allocation? It seems such a simple and
reasonable idea. Moreover, why isn't there a required compiler flag
that when used will cause the compiler to generate an error when
undefined behavior is encountered? Oh, yeah, it's called LINT!

Now I suppose I am in over my head discoursing such weighty issues with
an erudite C programmer such as yourself. I am by my own admission just
an old country programmer trying to make a living. But I think there is
some sensibility to what I suggest.

I am not finished yet, but I am feeling ill - like I might be having a
stroke - seriously!

Got to run.

--
Regards,
Stan Milam
================================================== ===========
Charter Member of The Society for Mediocre Guitar Playing on
Expensive Instruments, Ltd.
================================================== ===========
Dec 6 '06 #59
Stan Milam said:

<snip>
Why not
define values for errno when invalid argument values are used and when
no memory is available for allocation? It seems such a simple and
reasonable idea.
Implementors do not introduce extensions that they consider complicated and
unreasonable - at least, not often! Nevertheless, the mere introduction of
a simple and reasonable extension by one implementor does not oblige ISO to
adopt that extension and standardise it. They might do so, but they might
not. If you disagree with their decision, by all means take it up with
them. If you are sufficiently persuasive, maybe EINVAL and ENOMEM will
finally make it into the Standard.
Moreover, why isn't there a required compiler flag
that when used will cause the compiler to generate an error when
undefined behavior is encountered?
What should the compiler do with the following code, if such a flag is in
operation?

#include <stddef.h>
void foo(int *p, int *q, size_t len)
{
while(len--)
{
*p++ = *q++;
}
}

Do we need a compiler error ("Error: undefined behaviour in foo()") here, or
not? The answer is: it all depends. Specifically, it depends on how the
function is called. And the compiler might never see this code and the
calling code in the same invocation.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Dec 6 '06 #60
Roland Pibinger wrote:
On Sat, 02 Dec 2006 23:53:26 +0100, jacob navia wrote:
Reading comp.std.c
...
It proposes really interesting functions, among others getline and
getdelim, that I introduced into lcc-win32 (by coincidence) a few weeks
ago.
It proposes strdup and strndup too. Lcc-win32 proposes already strdup,
but strndup was missing.

strdup, getline and other functions require deallocation by the user.
So does malloc, calloc, and realloc. In a very similar sense, so does
fopen.
They were deliberately excluded from the C Standards.
Indeed, and gets was deliberately kept in, and the C *language* is
responsible for something like 75% of all security exploits in
existence. At this point, someone should call 3 strikes and you're
out.
[...] Not by
oversight, not because they were difficult to implement, not because
they wouldn't have been 'useful'.
And not for any good reason either. I would have some sympathy if they
demanded a name change to: strcpyalloc. Then they could assert a
simple naming pattern: functions ending in "alloc" need to return their
allocated storage to free(). Whatever, I wouldn't take any action by
the C standard committee to suggest that such a course of action is
even plausibly rational.

--
Paul Hsieh
http://www.pobox.com/~qed/
http://bstring.sf.net/

Dec 6 '06 #61
Roland Pibinger wrote:
On Sun, 03 Dec 2006 12:49:37 +0100, jacob navia wrote:
1) What's wrong with the user deallocating?

It's bad style.
Yes, but that would make it more consistent with C's design. I mean
the C language makes myspace.com look elegant and attractive.
[...] The responsibility for deallocation becomes unclear.
In your program you have some functions that return a char* that must
be freed and other functions retruning char* without that requirement:
a perfect receipt for a leaking program.
This sounds like an argument for removing malloc/calloc/realloc and
fopen from the standard.
Moreover, functions like getline foster an inefficient style. They
dynamically allocate memory for each line even when most of the lines
would fit into a char[80] buffer and only exceptional cases needed
dynamic allocation.
You sir, are the kind of person that virus/exploit writers have wet
dreams about. They know you exist, and they spend their time
fantasizing about you.
2) Maybe this view is changing since that technical report is there...

Why should they abandon good style?
Doesn't that assume they had some good style that they were abandoning
in the first place?

--
Paul Hsieh
http://www.pobox.com/~qed/
http://bstring.sf.net/

Dec 6 '06 #62
On Tue, 05 Dec 2006 20:21:30 GMT, Keith Thompson wrote:
>rl*@hoekstra-uitgeverij.nl (Richard Bos) writes:
>rp*****@yahoo.com (Roland Pibinger) wrote:
>>On Sun, 03 Dec 2006 10:01:01 -0500, CBFalconer wrote:
Not to mention fopen.

Wrong analogy again. Would you write a function like the following
(probably not):

/* user must call fclose() on the returned FILE* */
FILE *do_something (int i);

Yes, I would definitely write a function like that. It is very useful
for, say, opening a log file and writing a standardised header to it.
The calling function(s) then write log entries to it, and close it when
it's no longer needed.
But it's clearer to write

FILE* log = fopen(...);
write_log_header (log);
fclose (log);
>That's a good example. In effect, the function is a wrapper around
fopen().
Where do you find that style? Certainly not in K&R.
>If you absolutely insist on having strict pairings of
functions for allocation and deallocation, you could write
FILE *open_log(int i);
int close_log(FILE *log);
but close_log would do exactly the same thing as fclose().
The point of open_log and close_log is that they refer to a 'log
device' which needs not be a file. When you use FILE* in the interface
you cannot change the log destination without breaking user code. You
probably also use a write_log function (instead of fwrite) which
prepends the log enty with a timestamp, line number, ...
>In general, some functions allocate resources, and other functions
deallocate those same resources. Having a strict one-to-one mapping
between the two can be helpful, I suppose, but IMHO it's not strictly
necessary.
It's not necessary but it helps you create large-scale applications.
It's an important idiom to keep track of the resources in a C program.

>Even the standard memory allocation functions don't do
this; malloc() and calloc() both allocate memory, free() deallocates
it, and realloc() potentially does both. The clean symmetry of
fopen() and fclose() is broken by freopen().
Not by freopen() which just associates the existing stream with a new
file.
>Programmers simply have to *read the documentation* to find out which
function does what.
Yes, always, but that's not the point here.
>The interface described by the documentation
should be as simple as possible, but no simpler. If it makes sense to
have a strict pairing of allocators and deallocators, by all means do
that; if it doesn't, don't.
Programming in any language becomes manageable only when people adhere
to certain styles and idioms. If you merely knew the language syntax
you would know handly anything of a language. IMO, it's important to
propagate idioms that 'work' and warn of those that don't.
>(In OO terms, there's no requirement to have exactly one constructor
and exactly one destructor for a given type.)
I don't see a problem in more than one open/create/init function per
'object', e.g. open_log1(), open_log2(), ...

Best regards,
Roland Pibinger
Dec 6 '06 #63
rp*****@yahoo.com (Roland Pibinger) wrote:
On Tue, 05 Dec 2006 20:21:30 GMT, Keith Thompson wrote:
rl*@hoekstra-uitgeverij.nl (Richard Bos) writes:
rp*****@yahoo.com (Roland Pibinger) wrote:
On Sun, 03 Dec 2006 10:01:01 -0500, CBFalconer wrote:
Not to mention fopen.

Wrong analogy again. Would you write a function like the following
(probably not):

/* user must call fclose() on the returned FILE* */
FILE *do_something (int i);

Yes, I would definitely write a function like that. It is very useful
for, say, opening a log file and writing a standardised header to it.
The calling function(s) then write log entries to it, and close it when
it's no longer needed.

But it's clearer to write

FILE* log = fopen(...);
write_log_header (log);
fclose (log);
Says you. You're probably right if it happens once. But if you have over
a dozen places in your program where you start a log file?
That's a good example. In effect, the function is a wrapper around
fopen().

Where do you find that style? Certainly not in K&R.
I don't find so many styles in K&R. I don't think you'll find sparse
arrays in K&R. Does that mean we shouldn't use them?
Programmers simply have to *read the documentation* to find out which
function does what.

Yes, always, but that's not the point here.
Yes, it is. If you read the documentation for start_logfile(), you will
read that you need to call fclose() to close the log file. If you do not
read that documentation, you will indeed be completely puzzled by this
"unclear" style, but then you're a fool.
The interface described by the documentation
should be as simple as possible, but no simpler. If it makes sense to
have a strict pairing of allocators and deallocators, by all means do
that; if it doesn't, don't.

Programming in any language becomes manageable only when people adhere
to certain styles and idioms. If you merely knew the language syntax
you would know handly anything of a language. IMO, it's important to
propagate idioms that 'work' and warn of those that don't.
And this idiom works. IMnot very humbleO _and_ E.

Richard
Dec 6 '06 #64
Richard Heathfield wrote:
>
What should the compiler do with the following code, if such a flag is in
operation?

#include <stddef.h>
void foo(int *p, int *q, size_t len)
{
while(len--)
{
*p++ = *q++;
}
}

Do we need a compiler error ("Error: undefined behaviour in foo()") here, or
not? The answer is: it all depends. Specifically, it depends on how the
function is called. And the compiler might never see this code and the
calling code in the same invocation.
If that is what it takes, then yes. And what I meant was that before
any function made its way into a production library or program it would
have to be compiled with said flag. You can remove all of the ambiguity
of the above code:

for (; len; p++, q++, len-- ) *p = *q;

Which is what is happening and what you intended.
--
Regards,
Stan Milam
================================================== ===========
Charter Member of The Society for Mediocre Guitar Playing on
Expensive Instruments, Ltd.
================================================== ===========
Dec 7 '06 #65
CBFalconer wrote:
Stan Milam wrote:
> Now,
if the validations are good and the memory allocation fails errno
will be set to ENOMEM. Now you know why you failed and can get the
error message with strerror().

In part because I disapprove of global variables.
Well, at least we have one thing in common.
--
Regards,
Stan Milam
================================================== ===========
Charter Member of The Society for Mediocre Guitar Playing on
Expensive Instruments, Ltd.
================================================== ===========
Dec 7 '06 #66

On Thu, 7 Dec 2006, Stan Milam wrote:
>
Richard Heathfield wrote:
[re: a hypothetical compiler flag "-warn-on-UB"]
>What should the compiler do with the following code, if such a flag is in
operation?

#include <stddef.h>
void foo(int *p, int *q, size_t len)
{
while(len--)
{
*p++ = *q++;
}
}

Do we need a compiler error ("Error: undefined behaviour in foo()") here,
or not? The answer is: it all depends. Specifically, it depends on how the
function is called. And the compiler might never see this code and the
calling code in the same invocation.

If that is what it takes, then yes. And what I meant was that before any
function made its way into a production library or program it would have to
be compiled with said flag. You can remove all of the ambiguity of the above
code:

for (; len; p++, q++, len-- ) *p = *q;

Which is what is happening and what you intended.
However, you have not removed any of the possible undefined behaviors
of that code. (IMO, your revised version is harder to read, too, so it
looks like a lose-lose!)

Consider that *p++ increments p, /then/ dereferences it; and then
consider what happens if p's value is null or indeterminate.

-Arthur
Dec 7 '06 #67
Stan Milam wrote:
Richard Heathfield wrote:
>>
What should the compiler do with the following code, if such a
flag is in operation?

#include <stddef.h>
void foo(int *p, int *q, size_t len)
{
while(len--)
{
*p++ = *q++;
}
}

Do we need a compiler error ("Error: undefined behaviour in foo()")
here, or not? The answer is: it all depends. Specifically, it
depends on how the function is called. And the compiler might never
see this code and the calling code in the same invocation.

If that is what it takes, then yes. And what I meant was that
before any function made its way into a production library or
program it would have to be compiled with said flag. You can remove
all of the ambiguity of the above code:

for (; len; p++, q++, len-- ) *p = *q;

Which is what is happening and what you intended.
Why obfuscate the original, and simple:

while (len--) *p++ = *q++;

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>

Dec 7 '06 #68
Stan Milam said:

<snip>
And what I meant was that before
any function made its way into a production library or program it would
have to be compiled with said flag. You can remove all of the ambiguity
of the above code:

for (; len; p++, q++, len-- ) *p = *q;
If I understand you correctly, your ideal compiler would reject this code
because it might exhibit undefined behaviour.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Dec 7 '06 #69

This thread has been closed and replies have been disabled. Please start a new discussion.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.