Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #3965 > unrolled thread
| Started by | janus <emekamicro@gmail.com> |
|---|---|
| First post | 2011-05-14 11:15 -0700 |
| Last post | 2011-05-15 07:58 -0400 |
| Articles | 16 — 8 participants |
Back to article view | Back to comp.lang.c
Re: I need help janus <emekamicro@gmail.com> - 2011-05-14 11:15 -0700
Re: I need help "Heinrich Wolf" <invalid@invalid.invalid> - 2011-05-14 20:29 +0200
Re: I need help Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-05-15 13:03 +0300
Re: I need help "Heinrich Wolf" <invalid@invalid.invalid> - 2011-05-15 13:18 +0200
Re: I need help Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-05-16 04:31 +0300
Re: I need help Eric Sosman <esosman@ieee-dot-org.invalid> - 2011-05-15 08:13 -0400
Re: I need help "Heinrich Wolf" <invalid@invalid.invalid> - 2011-05-15 14:30 +0200
Re: I need help Eric Sosman <esosman@ieee-dot-org.invalid> - 2011-05-15 08:45 -0400
Re: I need help Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-05-16 04:34 +0300
Re: I need help Ian Collins <ian-news@hotmail.com> - 2011-05-16 13:42 +1200
Re: I need help Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-05-16 03:28 +0100
Re: I need help pete <pfiland@mindspring.com> - 2011-05-15 22:45 -0400
Re: I need help Ian Collins <ian-news@hotmail.com> - 2011-05-16 14:50 +1200
Re: I need help "Heinrich Wolf" <invalid@invalid.invalid> - 2011-05-16 12:26 +0200
Re: I need help Keith Thompson <kst-u@mib.org> - 2011-05-14 11:33 -0700
Re: I need help Eric Sosman <esosman@ieee-dot-org.invalid> - 2011-05-15 07:58 -0400
| From | janus <emekamicro@gmail.com> |
|---|---|
| Date | 2011-05-14 11:15 -0700 |
| Subject | Re: I need help |
| Message-ID | <45f62c12-a439-42b7-be27-bab7c954e209@glegroupsg2000goo.googlegroups.com> |
Another thing it is likely to print is "SIGSEGV" or "SIGBUS" or "General Protection Fault" or something along those lines. The anonymous array created by the string literal is not `const', but that's just an accident of history. Trying to modify such an array yields undefined behavior -- and indeed, plenty of compilers will put the arrays in read-only memory. (This allows them to save space by allocating just one array to hold both of "over" and "recover".) I am a bit confused by the above... Is the correct? char* string = "NEW"; strcat(string, "Jersey"); If string is in read-only memory, could it still support things like concatenation? Janus
[toc] | [next] | [standalone]
| From | "Heinrich Wolf" <invalid@invalid.invalid> |
|---|---|
| Date | 2011-05-14 20:29 +0200 |
| Message-ID | <iqmhmk$5mt$1@news.m-online.net> |
| In reply to | #3965 |
"janus" <emekamicro@gmail.com> schrieb im Newsbeitrag news:45f62c12-a439-42b7-be27-bab7c954e209@glegroupsg2000goo.googlegroups.com... ... > Is the correct? > > char* string = "NEW"; > strcat(string, "Jersey"); > > If string is in read-only memory, could it still support things like > concatenation? > > Janus read-only memory does not support concatenation either. And there is yet another problem when you code: char string[] = "NEW"; strcat(string, "Jersey"); You do not reserve space to hold the concatenated string. Here is how you could do it: char string[10] = "NEW"; strcat(string, "Jersey"); However strcat has the danger to run out of string size. I always code that: char string[10] = "NEW"; strncat(string, "Jersey", sizeof(string) - strlen(string) - 1); or with a macro: #define STRNCAT(a, b) strncat(a, b, sizeof(a) - strlen(a) - 1) char string[10] = "NEW"; STRNCAT(string, "Jersey");
[toc] | [prev] | [next] | [standalone]
| From | Phil Carmody <thefatphil_demunged@yahoo.co.uk> |
|---|---|
| Date | 2011-05-15 13:03 +0300 |
| Message-ID | <87mxiouvp8.fsf@bazspaz.fatphil.org> |
| In reply to | #3967 |
"Heinrich Wolf" <invalid@invalid.invalid> writes: > "janus" <emekamicro@gmail.com> schrieb im Newsbeitrag > news:45f62c12-a439-42b7-be27-bab7c954e209@glegroupsg2000goo.googlegroups.com... > ... > > Is the correct? > > > > char* string = "NEW"; > > strcat(string, "Jersey"); > > > > If string is in read-only memory, could it still support things like > > concatenation? > > > > Janus > > read-only memory does not support concatenation either. And there is > yet another problem when you code: > > char string[] = "NEW"; > strcat(string, "Jersey"); > > You do not reserve space to hold the concatenated string. Here is how > you could do it: > > char string[10] = "NEW"; > strcat(string, "Jersey"); > > However strcat has the danger to run out of string size. I always code that: > > char string[10] = "NEW"; > strncat(string, "Jersey", sizeof(string) - strlen(string) - 1); Why do you want to scan accross "NEW" twice? Once in the strlen, and once in the strncat. Phil -- "At least you know where you are with Microsoft." "True. I just wish I'd brought a paddle." -- Matthew Vernon
[toc] | [prev] | [next] | [standalone]
| From | "Heinrich Wolf" <invalid@invalid.invalid> |
|---|---|
| Date | 2011-05-15 13:18 +0200 |
| Message-ID | <iqocr0$8ij$1@news.m-online.net> |
| In reply to | #4003 |
"Phil Carmody" <thefatphil_demunged@yahoo.co.uk> schrieb im Newsbeitrag news:87mxiouvp8.fsf@bazspaz.fatphil.org... ... > Why do you want to scan accross "NEW" twice? Once in the strlen, and > once in the strncat. I know that I could save some microseconds with size_t l = strlen(a); strncat(a + l, b, sizeof(a) - l - 1); but STRNCAT has done a good job many years and is easy to read.
[toc] | [prev] | [next] | [standalone]
| From | Phil Carmody <thefatphil_demunged@yahoo.co.uk> |
|---|---|
| Date | 2011-05-16 04:31 +0300 |
| Message-ID | <87aaenv3be.fsf@bazspaz.fatphil.org> |
| In reply to | #4005 |
"Heinrich Wolf" <invalid@invalid.invalid> writes: > "Phil Carmody" <thefatphil_demunged@yahoo.co.uk> schrieb im > Newsbeitrag news:87mxiouvp8.fsf@bazspaz.fatphil.org... > ... > > Why do you want to scan accross "NEW" twice? Once in the strlen, and > > once in the strncat. > > I know that I could save some microseconds You knew you always knew the ratio of the length of the left string compared to the right string? Wow, you're a lucky man. I wish I could be so certain that arbitrary input was so predictable. Phil -- "At least you know where you are with Microsoft." "True. I just wish I'd brought a paddle." -- Matthew Vernon
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@ieee-dot-org.invalid> |
|---|---|
| Date | 2011-05-15 08:13 -0400 |
| Message-ID | <iqog3e$27h$1@dont-email.me> |
| In reply to | #3967 |
On 5/14/2011 2:29 PM, Heinrich Wolf wrote:
>[...]
> However strcat has the danger to run out of string size. I always code
> that:
>
> char string[10] = "NEW";
> strncat(string, "Jersey", sizeof(string) - strlen(string) - 1);
>
> or with a macro:
>
> #define STRNCAT(a, b) strncat(a, b, sizeof(a) - strlen(a) - 1)
> char string[10] = "NEW";
> STRNCAT(string, "Jersey");
If you like this sort of thing, so be it -- I'm not convinced
there's much value in using training wheels, but tastes vary.
However, you ought to mention that this STRNCAT macro relies
on the pre-existing '\0' at the end of the output array. If
string[9] were '?' instead of '\0', STRNCAT would run happily but
leave you with a non-terminated string, just waiting to cause
unpleasant surprises later.
--
Eric Sosman
esosman@ieee-dot-org.invalid
[toc] | [prev] | [next] | [standalone]
| From | "Heinrich Wolf" <invalid@invalid.invalid> |
|---|---|
| Date | 2011-05-15 14:30 +0200 |
| Message-ID | <iqoh10$ahj$1@news.m-online.net> |
| In reply to | #4010 |
"Eric Sosman" <esosman@ieee-dot-org.invalid> schrieb im Newsbeitrag news:iqog3e$27h$1@dont-email.me... ... > However, you ought to mention that this STRNCAT macro relies > on the pre-existing '\0' at the end of the output array. If > string[9] were '?' instead of '\0', STRNCAT would run happily but > leave you with a non-terminated string, just waiting to cause > unpleasant surprises later. ... No! strncat guarantees to append a terminating '\0' character, even if it needs to truncate the source string. That is the difference to strncpy. You do net need to memset(output, 0 sizeof(output)); The only prerequisite is, that output is terminated by a single '\0' before. But that is the same with strcat.
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@ieee-dot-org.invalid> |
|---|---|
| Date | 2011-05-15 08:45 -0400 |
| Message-ID | <iqohu1$aa1$1@dont-email.me> |
| In reply to | #4012 |
On 5/15/2011 8:30 AM, Heinrich Wolf wrote:
>
> "Eric Sosman" <esosman@ieee-dot-org.invalid> schrieb im Newsbeitrag
> news:iqog3e$27h$1@dont-email.me...
> ...
>> However, you ought to mention that this STRNCAT macro relies
>> on the pre-existing '\0' at the end of the output array. If
>> string[9] were '?' instead of '\0', STRNCAT would run happily but
>> leave you with a non-terminated string, just waiting to cause
>> unpleasant surprises later.
> ...
> No! strncat guarantees to append a terminating '\0' character, even if
> it needs to truncate the source string. That is the difference to
> strncpy. You do net need to memset(output, 0 sizeof(output)); The only
> prerequisite is, that output is terminated by a single '\0' before. But
> that is the same with strcat.
My apologies: I confused `strncat' with `strncpy'.
--
Eric Sosman
esosman@ieee-dot-org.invalid
[toc] | [prev] | [next] | [standalone]
| From | Phil Carmody <thefatphil_demunged@yahoo.co.uk> |
|---|---|
| Date | 2011-05-16 04:34 +0300 |
| Message-ID | <8762pbv36u.fsf@bazspaz.fatphil.org> |
| In reply to | #4015 |
Eric Sosman <esosman@ieee-dot-org.invalid> writes: > On 5/15/2011 8:30 AM, Heinrich Wolf wrote: > > > > "Eric Sosman" <esosman@ieee-dot-org.invalid> schrieb im Newsbeitrag > > news:iqog3e$27h$1@dont-email.me... > > ... > >> However, you ought to mention that this STRNCAT macro relies > >> on the pre-existing '\0' at the end of the output array. If > >> string[9] were '?' instead of '\0', STRNCAT would run happily but > >> leave you with a non-terminated string, just waiting to cause > >> unpleasant surprises later. > > ... > > No! strncat guarantees to append a terminating '\0' character, even if > > it needs to truncate the source string. That is the difference to > > strncpy. You do net need to memset(output, 0 sizeof(output)); The only > > prerequisite is, that output is terminated by a single '\0' before. But > > that is the same with strcat. > > My apologies: I confused `strncat' with `strncpy'. Votes for abolishing srtncat? 1 here; I trust the above is enough of a reason to come on board, and from what Heinrich has posted, hopefully there's a 3rd vote too. Phil -- "At least you know where you are with Microsoft." "True. I just wish I'd brought a paddle." -- Matthew Vernon
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2011-05-16 13:42 +1200 |
| Message-ID | <93bdoaFlpiU2@mid.individual.net> |
| In reply to | #3967 |
On 05/15/11 06:29 AM, Heinrich Wolf wrote: > > or with a macro: > > #define STRNCAT(a, b) strncat(a, b, sizeof(a) - strlen(a) - 1) > char string[10] = "NEW"; > STRNCAT(string, "Jersey"); That macro would go horribly (and silently) wrong if a) 'a' wasn't a fixed sized array, or b) it was, but the definition wasn't visible when the macro was expanded. -- Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2011-05-16 03:28 +0100 |
| Message-ID | <0.34713e4d8eed4d5fd987.20110516032856BST.87pqnjwf87.fsf@bsb.me.uk> |
| In reply to | #4047 |
Ian Collins <ian-news@hotmail.com> writes: > On 05/15/11 06:29 AM, Heinrich Wolf wrote: >> >> or with a macro: >> >> #define STRNCAT(a, b) strncat(a, b, sizeof(a) - strlen(a) - 1) >> char string[10] = "NEW"; >> STRNCAT(string, "Jersey"); > > That macro would go horribly (and silently) wrong if > > a) 'a' wasn't a fixed sized array, or I don't think "fixed size" conveys what you want. It might be seen to contrast with variably modified arrays, but they work just as well (or as badly) as any other. I think you wanted to suggest that 'a' might be a pointer rather than an array. If not, I'll add: a1) 'a' expands not to the name of an array but to a pointer expression. > b) it was, but the definition wasn't visible when the macro was expanded. I can't think how this could go silently wrong, but it sounds bad! I'd add c) strlen(a) >= sizeof(a) simply because it goes wrong in a way that is often unexpected. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | pete <pfiland@mindspring.com> |
|---|---|
| Date | 2011-05-15 22:45 -0400 |
| Message-ID | <4DD08FAE.15B3@mindspring.com> |
| In reply to | #4047 |
Ian Collins wrote: > > On 05/15/11 06:29 AM, Heinrich Wolf wrote: > > > > or with a macro: > > > > #define STRNCAT(a, b) strncat(a, b, sizeof(a) - strlen(a) - 1) > > char string[10] = "NEW"; > > STRNCAT(string, "Jersey"); > > That macro would go horribly (and silently) wrong if > > a) 'a' wasn't a fixed sized array, or > b) it was, but the definition wasn't visible > when the macro was expanded. If (a) was a fixed sized array, but the definition wasn't visible when the macro was expanded, then (a) would be an incomplete type and (sizeof a) would cause the generation of a diagnostic message, rather than go silently wrong. -- pete
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2011-05-16 14:50 +1200 |
| Message-ID | <93bhneFlpiU4@mid.individual.net> |
| In reply to | #4050 |
On 05/16/11 02:45 PM, pete wrote: > Ian Collins wrote: >> >> On 05/15/11 06:29 AM, Heinrich Wolf wrote: >>> >>> or with a macro: >>> >>> #define STRNCAT(a, b) strncat(a, b, sizeof(a) - strlen(a) - 1) >>> char string[10] = "NEW"; >>> STRNCAT(string, "Jersey"); >> >> That macro would go horribly (and silently) wrong if >> >> a) 'a' wasn't a fixed sized array, or >> b) it was, but the definition wasn't visible >> when the macro was expanded. > > If (a) was a fixed sized array, > but the definition wasn't visible when the macro was expanded, > then (a) would be an incomplete type > and (sizeof a) would cause the generation of a diagnostic message, > rather than go silently wrong. Well OK, I was thinking an extern pointer declaration, but that would be a messy mix. -- Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | "Heinrich Wolf" <invalid@invalid.invalid> |
|---|---|
| Date | 2011-05-16 12:26 +0200 |
| Message-ID | <iqqu58$d8r$1@news.m-online.net> |
| In reply to | #4047 |
"Ian Collins" <ian-news@hotmail.com> schrieb im Newsbeitrag
news:93bdoaFlpiU2@mid.individual.net...
> On 05/15/11 06:29 AM, Heinrich Wolf wrote:
>>
>> or with a macro:
>>
>> #define STRNCAT(a, b) strncat(a, b, sizeof(a) - strlen(a) - 1)
>> char string[10] = "NEW";
>> STRNCAT(string, "Jersey");
>
> That macro would go horribly (and silently) wrong if
>
> a) 'a' wasn't a fixed sized array, or
> b) it was, but the definition wasn't visible when the macro was expanded.
>
> --
> Ian Collins
You must not use the macro STRNCAT in e.g. this case:
void a_procedure(char *a)
{
STRNCAT(a, "Jersey");
}
int main(void)
{
char string[10] = "NEW";
a_procedure(string);
}
Here sizeof(a) is the size of a pointer and not the size of string. Instead
you could do it without the macro:
void a_procedure(char *a, size_t size)
{
strncat(a, "Jersey", size - strlen(a) - 1);
}
int main(void)
{
char string[10] = "NEW";
a_procedure(string, sizeof(string));
}
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2011-05-14 11:33 -0700 |
| Message-ID | <lnsjshgmic.fsf@nuthaus.mib.org> |
| In reply to | #3965 |
janus <emekamicro@gmail.com> writes:
> Another thing it is likely to print is "SIGSEGV" or "SIGBUS" or
> "General Protection Fault" or something along those lines. The
> anonymous array created by the string literal is not `const', but
> that's just an accident of history. Trying to modify such an array
> yields undefined behavior -- and indeed, plenty of compilers will
> put the arrays in read-only memory. (This allows them to save space
> by allocating just one array to hold both of "over" and "recover".)
>
> I am a bit confused by the above...
>
> Is the correct?
>
> char* string = "NEW";
> strcat(string, "Jersey");
>
> If string is in read-only memory, could it still support things like
> concatenation?
No.
On my system, a program containing those two lines died with a
segmentation fault.
But of course that's not the only possible result. String literals
(more accurately, the static arrays associated with them) aren't
*necessarily* stored in read-only memory. The strcat() call will
attempt to store the 7 characters of "Jersey" (6 plus the trailing
'\0') at locations starting after the 'W' in "NEW". This might
appear to work, if that area of memory happens to be writable
and happens not to be used for anything else. On the other hand,
it could clobber some other variable, or write over some internal
information (such as the function's return address), with arbitrarily
bad results that might not even appear until later.
And the phrase "will attempt" above isn't strictly correct. Since
the behavior is undefined, strcat() could conceivably detect that it
won't be able to write the characters and do something else instead.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@ieee-dot-org.invalid> |
|---|---|
| Date | 2011-05-15 07:58 -0400 |
| Message-ID | <iqof6p$sbc$1@dont-email.me> |
| In reply to | #3965 |
On 5/14/2011 2:15 PM, janus wrote:
> Another thing it is likely to print is "SIGSEGV" or "SIGBUS" or
> "General Protection Fault" or something along those lines. The
> anonymous array created by the string literal is not `const', but
> that's just an accident of history. Trying to modify such an array
> yields undefined behavior -- and indeed, plenty of compilers will
> put the arrays in read-only memory. (This allows them to save space
> by allocating just one array to hold both of "over" and "recover".)
>
> I am a bit confused by the above...
It is customary to mark the material you quote, making it
distinguishable from material of your own authorship. See those
greater-than signs at the left margin? Most news clients or mail
clients will insert them for you.
It is also customary to attribute the quoted material to its
author (or authors), so that readers aren't misled into thinking
its your own. See that "On...janus wrote:" line at the top?
Again, most news clients or mail clients will insert such lines
for you.
To use the medium effectively, first learn to use the medium.
> Is the correct?
>
> char* string = "NEW";
> strcat(string, "Jersey");
Undefined behavior.
> If string is in read-only memory, could it still support things like concatenation?
No.
Nor should it. Think of it this way: A string literal (when
used this way) is notionally a constant, much like 42 or 3.14. If
you start modifying constants, things will become very confusing
very rapidly:
int i = 6;
6 *= 7; /* not legal; just imagine */
int j = 6; /* does j have the value forty-two? */
Similarly with string constants: By concatenating to a string (or
by changing one or more of its existing characters), you change
the value of that string. So:
char *message = "Hello, world!";
strcpy(message, "Go to Hell!"); /* not legal; just imagine */
puts(message); /* friendly, or confrontational? */
You don't (or shouldn't) want to change a constant, and C doesn't
promise that an attempt to do so will succeed. (Doesn't promise
anything at all about what will happen, actually.)
--
Eric Sosman
esosman@ieee-dot-org.invalid
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.c
csiph-web