Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #3965 > unrolled thread

Re: I need help

Started byjanus <emekamicro@gmail.com>
First post2011-05-14 11:15 -0700
Last post2011-05-15 07:58 -0400
Articles 16 — 8 participants

Back to article view | Back to comp.lang.c


Contents

  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

#3965 — Re: I need help

Fromjanus <emekamicro@gmail.com>
Date2011-05-14 11:15 -0700
SubjectRe: 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]


#3967

From"Heinrich Wolf" <invalid@invalid.invalid>
Date2011-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]


#4003

FromPhil Carmody <thefatphil_demunged@yahoo.co.uk>
Date2011-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]


#4005

From"Heinrich Wolf" <invalid@invalid.invalid>
Date2011-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]


#4043

FromPhil Carmody <thefatphil_demunged@yahoo.co.uk>
Date2011-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]


#4010

FromEric Sosman <esosman@ieee-dot-org.invalid>
Date2011-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]


#4012

From"Heinrich Wolf" <invalid@invalid.invalid>
Date2011-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]


#4015

FromEric Sosman <esosman@ieee-dot-org.invalid>
Date2011-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]


#4045

FromPhil Carmody <thefatphil_demunged@yahoo.co.uk>
Date2011-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]


#4047

FromIan Collins <ian-news@hotmail.com>
Date2011-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]


#4049

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2011-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]


#4050

Frompete <pfiland@mindspring.com>
Date2011-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]


#4051

FromIan Collins <ian-news@hotmail.com>
Date2011-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]


#4060

From"Heinrich Wolf" <invalid@invalid.invalid>
Date2011-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]


#3969

FromKeith Thompson <kst-u@mib.org>
Date2011-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]


#4008

FromEric Sosman <esosman@ieee-dot-org.invalid>
Date2011-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