Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #6755 > unrolled thread
| Started by | "sumit.sharma" <nospam@nospam.com> |
|---|---|
| First post | 2011-06-23 20:07 +0000 |
| Last post | 2011-06-23 17:13 -0600 |
| Articles | 20 on this page of 28 — 12 participants |
Back to article view | Back to comp.lang.c
Query abt union "sumit.sharma" <nospam@nospam.com> - 2011-06-23 20:07 +0000
Re: Query abt union Ben Pfaff <blp@cs.stanford.edu> - 2011-06-23 13:18 -0700
Re: Query abt union Shao Miller <sha0.miller@gmail.com> - 2011-06-23 17:20 -0500
Re: Query abt union James Waldby <not@valid.invalid> - 2011-06-24 17:34 +0000
Re: Query abt union Shao Miller <sha0.miller@gmail.com> - 2011-06-24 14:42 -0400
Re: Query abt union James Waldby <not@valid.invalid> - 2011-06-24 21:13 +0000
Re: Query abt union Shao Miller <sha0.miller@gmail.com> - 2011-06-26 14:08 -0500
Re: Query abt union James Waldby <not@valid.invalid> - 2011-06-27 05:13 +0000
Re: Query abt union John Gordon <gordon@panix.com> - 2011-06-23 22:27 +0000
Re: Query abt union Lew Pitcher <lpitcher@teksavvy.com> - 2011-06-23 18:47 -0400
Re: Query abt union Shao Miller <sha0.miller@gmail.com> - 2011-06-23 17:54 -0500
Re: Query abt union Keith Thompson <kst-u@mib.org> - 2011-06-23 17:19 -0700
Re: Query abt union Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2011-06-23 22:12 -0600
Re: Query abt union Keith Thompson <kst-u@mib.org> - 2011-06-23 22:32 -0700
Re: Query abt union Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2011-06-24 08:51 -0600
Re: Query abt union Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-06-24 16:30 +0100
Re: Query abt union pete <pfiland@mindspring.com> - 2011-06-24 12:46 -0400
Re: Query abt union Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2011-06-24 16:18 -0600
Re: Query abt union pozz <pozzugno@gmail.com> - 2011-06-24 23:14 +0200
Re: Query abt union John Gordon <gordon@panix.com> - 2011-06-24 21:37 +0000
Re: Query abt union Shao Miller <sha0.miller@gmail.com> - 2011-06-26 14:28 -0500
Re: Query abt union Keith Thompson <kst-u@mib.org> - 2011-06-24 14:56 -0700
Re: Query abt union Edward Rutherford <edward.p.rutherford79@REMOVETHIS.gmail.com> - 2011-06-24 22:10 +0000
Re: Query abt union Keith Thompson <kst-u@mib.org> - 2011-06-24 15:41 -0700
Re: Query abt union pete <pfiland@mindspring.com> - 2011-06-25 10:33 -0400
Re: Query abt union pete <pfiland@mindspring.com> - 2011-06-25 15:30 -0400
Re: Query abt union Shao Miller <sha0.miller@gmail.com> - 2011-06-26 14:12 -0500
Re: Query abt union Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2011-06-23 17:13 -0600
Page 1 of 2 [1] 2 Next page →
| From | "sumit.sharma" <nospam@nospam.com> |
|---|---|
| Date | 2011-06-23 20:07 +0000 |
| Subject | Query abt union |
| Message-ID | <iu06d5$cnu$1@speranza.aioe.org> |
Hi,
I have some experience in C prog lang. I have small doubt abt using
unions in C lang.
I have the foll. union
union MyUnion
{
char name [100];
double dblval;
int intVal;
};
Since all the members of union share the same memory space, if we set
the val of one union members, it overwr. the other field's value.
How do the OS maintain that a partic. member is set and not the
other member.
Say like, I use
MyUnion ux;
strncpy(ux.name, "C Language", strlen("C Langage")); /* name is set */
/* try to overwr. name field */
ux.intVal = 0xFF6677;
Now at this time how does OS maintains that intVal is now used... !!!!
Also, if I now try to print name field, what it shld be ??
Pls reply in ur FREE time..there is no urgency..
sumit
[toc] | [next] | [standalone]
| From | Ben Pfaff <blp@cs.stanford.edu> |
|---|---|
| Date | 2011-06-23 13:18 -0700 |
| Message-ID | <87pqm4jo7u.fsf@blp.benpfaff.org> |
| In reply to | #6755 |
"sumit.sharma" <nospam@nospam.com> writes: [in a union] > How do the OS maintain that a partic. member is set and not the > other member. It doesn't. It's the responsibility of the code that uses to union to keep track of which member has most recently been assigned. -- Ben Pfaff http://benpfaff.org
[toc] | [prev] | [next] | [standalone]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2011-06-23 17:20 -0500 |
| Message-ID | <iu0e7v$vbb$1@dont-email.me> |
| In reply to | #6755 |
On 6/23/2011 3:07 PM, sumit.sharma wrote:
> Hi,
>
> I have some experience in C prog lang. I have small doubt abt using
> unions in C lang.
>
> I have the foll. union
>
> union MyUnion
> {
> char name [100];
> double dblval;
> int intVal;
> };
>
> Since all the members of union share the same memory space, if we set
> the val of one union members, it overwr. the other field's value.
> How do the OS maintain that a partic. member is set and not the
> other member.
>
> Say like, I use
>
> MyUnion ux;
>
I have a doubt about your line, above.
union MyUnion ux;
> strncpy(ux.name, "C Language", strlen("C Langage")); /* name is set */
>
I have a doubt about your line, above.
/* Set the 'name' member */
strncpy(ux.name, "C Language", sizeof ux.name);
> /* try to overwr. name field */
>
> ux.intVal = 0xFF6677;
>
> Now at this time how does OS maintains that intVal is now used... !!!!
>
Already answered by someone else.
> Also, if I now try to print name field, what it shld be ??
>
You should doubt that it will be useful as a "name".
[toc] | [prev] | [next] | [standalone]
| From | James Waldby <not@valid.invalid> |
|---|---|
| Date | 2011-06-24 17:34 +0000 |
| Message-ID | <iu2hq8$a8m$1@dont-email.me> |
| In reply to | #6764 |
On Thu, 23 Jun 2011 17:20:45 -0500, Shao Miller wrote:
> On 6/23/2011 3:07 PM, sumit.sharma wrote:
>> I have some experience in C prog lang. I have small doubt abt using
>> unions in C lang.
Note to OP -- For proper English usage, write 'question' rather
than 'doubt' in the above. Also, avoid glaringly stupid abbreviations
like abt, foll., overwr., partic., and shld. (Non-glaring stupid
abbreviations like prog lang and val perhaps are ok.)
>> I have the foll. union
>>
>> union MyUnion
>> {
>> char name [100];
>> double dblval;
>> int intVal;
>> };
>>
>> Since all the members of union share the same memory space, if we set
>> the val of one union members, it overwr. the other field's value. How
>> do the OS maintain that a partic. member is set and not the other
>> member.
...
>> MyUnion ux;
>>
> I have a doubt about your line, above.
>
> union MyUnion ux;
>
>> strncpy(ux.name, "C Language", strlen("C Langage")); /* ... */
>>
> I have a doubt about your line, above.
>
> /* Set the 'name' member */
> strncpy(ux.name, "C Language", sizeof ux.name);
...
On the one hand, the line you are correcting doesn't work [copies
"C Languag", not "C Language", into ux.name, and fails to terminate
string with nil]; on the other, your correction works inefficiently
as it writes 89 superfluous nil's into ux.name. I think a temperate
programmer would instead write
strcpy(ux.name, "C Language");
or
union MyUnion ux = {.name="C Language"};
or without '.name=', as in following code:
#include <stdio.h>
union MyUnion {
char name [100]; double dblval; int intVal; };
int main(void) {
union MyUnion ux = {"C Language"};
printf ("%s\n", ux.name);
ux.name[2] = 'l';
printf ("%s\n", ux.name);
ux.intVal += 32-(32<<16); /* not recommended */
printf ("%s\n", ux.name);
return 0;
}
On x86 linux/gcc systems and perhaps other x86 systems this outputs:
C Language
C language
c Language
--
jiw
[toc] | [prev] | [next] | [standalone]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2011-06-24 14:42 -0400 |
| Message-ID | <iu2ltg$6u8$1@dont-email.me> |
| In reply to | #6849 |
On 6/24/2011 13:34, James Waldby wrote:
> On Thu, 23 Jun 2011 17:20:45 -0500, Shao Miller wrote:
>> On 6/23/2011 3:07 PM, sumit.sharma wrote:
>>> I have some experience in C prog lang. I have small doubt abt using
>>> unions in C lang.
>
> Note to OP -- For proper English usage, write 'question' rather
> than 'doubt' in the above.
I expect another "doubt" before the end of the day.
>>> I have the foll. union
>>>
>>> union MyUnion
>>> {
>>> char name [100];
>>> double dblval;
>>> int intVal;
>>> };
>>>
>>> Since all the members of union share the same memory space, if we set
>>> the val of one union members, it overwr. the other field's value. How
>>> do the OS maintain that a partic. member is set and not the other
>>> member.
> ...
>>> MyUnion ux;
>>>
>> I have a doubt about your line, above.
>>
>> union MyUnion ux;
>>
>>> strncpy(ux.name, "C Language", strlen("C Langage")); /* ... */
>>>
>> I have a doubt about your line, above.
>>
>> /* Set the 'name' member */
>> strncpy(ux.name, "C Language", sizeof ux.name);
> ...
>
> On the one hand, the line you are correcting
"Suggesting," I'd say. The original intention is actually uncertain.
> doesn't work [copies
> "C Languag", not "C Language", into ux.name, and fails to terminate
> string with nil]; on the other, your correction works inefficiently
> as it writes 89 superfluous nil's into ux.name.
The line of code under discussion leaves _much_ to be desired, in my
opinion.
- Using 'strlen' on a string literal seems silly when one can use 'sizeof'.
- The string literal for 'strlen' is a character short due to
[presumably] a typographical error.
- _Without_ the typo., 'strlen' is going to yield a number of characters
that prevents the null character from being copied into the 'ux.name'
array. 'ux.name' will then not necessarily contain a string.
- Using any length related to the string literal for 'strncpy' is silly;
the limit ought to be related to the destination array, instead.
The line of code thus strikes me as... Suspicious. Suppose it's sincere:
Why did the original poster use 'strncpy', do you suppose? Did they
want some kind of safety? If so, what could be safer than the suggested:
strncpy(ux.name, "C Language", sizeof ux.name);
? Maybe following it with:
ux.name[sizeof ux.name - 1] = '\0';
?
The "inefficient" population of redundant null characters can be viewed
as a "safety" feature. Whatever garbage is there is cleared.
> I think a temperate
> programmer would instead write
> strcpy(ux.name, "C Language");
> or
> union MyUnion ux = {.name="C Language"};
> or without '.name=', as in following code:
>
> #include<stdio.h>
> union MyUnion {
> char name [100]; double dblval; int intVal; };
>
> int main(void) {
> union MyUnion ux = {"C Language"};
Please tell me about the difference in behaviour (in regards to
"efficiency," perhaps) between this initialization and the example
'strncpy' line I gave above as a suggestion to the original post.
> [...more code...]
Not that we'll ever read from this original poster again, like so many
others (and who might all be the very same, doubt-wielding poster).
[toc] | [prev] | [next] | [standalone]
| From | James Waldby <not@valid.invalid> |
|---|---|
| Date | 2011-06-24 21:13 +0000 |
| Message-ID | <iu2ulf$kj7$1@dont-email.me> |
| In reply to | #6855 |
On Fri, 24 Jun 2011 14:42:26 -0400, Shao Miller wrote:
> On 6/24/2011 13:34, James Waldby wrote:
>> On Thu, 23 Jun 2011 17:20:45 -0500, Shao Miller wrote:
>>> On 6/23/2011 3:07 PM, sumit.sharma wrote:
>>>> [snip]
>>> union MyUnion ux;
>>>
>>>> strncpy(ux.name, "C Language", strlen("C Langage")); /* ... */
>>>>
>>> I have a doubt about your line, above.
>>>
>>> /* Set the 'name' member */
>>> strncpy(ux.name, "C Language", sizeof ux.name);
>> ...
>> On the one hand, the line you are correcting
>
> "Suggesting," I'd say. The original intention is actually uncertain.
True!
>> doesn't work [copies "C Languag", not "C Language", into
>> ux.name, and fails to terminate string with nil]; on the
>> other, your correction works inefficiently as it writes 89
>> superfluous nil's into ux.name.
>
> The line of code under discussion leaves _much_ to be desired, in my
> opinion.
>
> - Using 'strlen' on a string literal seems silly when one can use
> 'sizeof'.
>
> - The string literal for 'strlen' is a character short due to
> [presumably] a typographical error.
>
> - _Without_ the typo., 'strlen' is going to yield a number of characters
> that prevents the null character from being copied into the 'ux.name'
> array. 'ux.name' will then not necessarily contain a string.
>
> - Using any length related to the string literal for 'strncpy' is silly;
> the limit ought to be related to the destination array, instead.
>
> The line of code thus strikes me as... Suspicious. Suppose it's
> sincere:
>
> Why did the original poster use 'strncpy', do you suppose? Did they
> want some kind of safety?
I imagine OP used strncpy() due to ignorance of alternatives, or
perhaps because of exposure to bad examples. In light of the
problems that you list above, a 'safety' rationale seems unlikely.
> If so, what could be safer than the suggested:
>
> strncpy(ux.name, "C Language", sizeof ux.name);
>
> ? Maybe following it with:
>
> ux.name[sizeof ux.name - 1] = '\0';
> ?
...
>> I think a temperate
>> programmer would instead write
>> strcpy(ux.name, "C Language");
>> or
>> union MyUnion ux = {.name="C Language"};
>> or without '.name=', as in following code:
>>
>> #include<stdio.h>
>> union MyUnion {
>> char name [100]; double dblval; int intVal; };
>>
>> int main(void) {
>> union MyUnion ux = {"C Language"};
>
> Please tell me about the difference in behaviour (in regards to
> "efficiency," perhaps) between this initialization and the example
> 'strncpy' line I gave above as a suggestion to the original post.
In comparing
union MyUnion ux = {"C Language"};
to separate declaration and initialization of ux, I see
efficiency as of far less importance than correctness, clarity,
and brevity, on which counts the combined statement excels. Of
course the combined statement *is* far more efficient, probably
saving over 10ns of runtime per program execution relative to
initialization by strcpy(), and probably over 50ns relative to
strncpy(), and saving easily a handful of bytes in program size.
--
jiw
[toc] | [prev] | [next] | [standalone]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2011-06-26 14:08 -0500 |
| Message-ID | <iu7sii$653$1@dont-email.me> |
| In reply to | #6884 |
On 6/24/2011 4:13 PM, James Waldby wrote:
>
> In comparing
> union MyUnion ux = {"C Language"};
> to separate declaration and initialization of ux, I see
> efficiency as of far less importance than correctness, clarity,
> and brevity, on which counts the combined statement excels.
Agreed.
> Of course the combined statement *is* far more efficient, probably
> saving over 10ns of runtime per program execution relative to
> initialization by strcpy(), and probably over 50ns relative to
> strncpy(), and saving easily a handful of bytes in program size.
>
I'm not sure that I understand why, for the case of 'strncpy'. Is it
because of the overhead of calling a function?
6.7.8p19 includes "... all subobjects that are not initialized
explicitly shall be initialized implicitly the same as objects that have
static storage duration."
Does that mean that the remaining elements of the 'ux' array are set to
null character values, just the same as 'strncpy' does?
I've seen a Microsoft compiler complain about:
void func(void) {
char foo[100] = {0};
return;
}
if the module providing 'memset' was not linked-with. It seems to me
that for this implementation, initializing with a string literal might
possibly employ 'strncpy' for the same reason as it employs 'memset' for
the initialization shown just above.
[toc] | [prev] | [next] | [standalone]
| From | James Waldby <not@valid.invalid> |
|---|---|
| Date | 2011-06-27 05:13 +0000 |
| Message-ID | <iu93h8$94i$1@dont-email.me> |
| In reply to | #6979 |
On Sun, 26 Jun 2011 14:08:13 -0500, Shao Miller wrote:
> On 6/24/2011 4:13 PM, James Waldby wrote:
>> In comparing
>> union MyUnion ux = {"C Language"};
>> to separate declaration and initialization of ux, I see efficiency as
>> of far less importance than correctness, clarity, and brevity, on which
>> counts the combined statement excels.
>
> Agreed.
>
>> Of course the combined statement *is* far more efficient, probably
>> saving over 10ns of runtime per program execution relative to
>> initialization by strcpy(), and probably over 50ns relative to
>> strncpy(), and saving easily a handful of bytes in program size.
>>
> I'm not sure that I understand why, for the case of 'strncpy'. Is it
> because of the overhead of calling a function?
The time savings I mentioned arise if ux has static storage duration
and its initial value is loaded along with the program (before
execution begins). There might not be many other eligible scenarios.
> 6.7.8p19 includes "... all subobjects that are not initialized
> explicitly shall be initialized implicitly the same as objects that have
> static storage duration."
>
> Does that mean that the remaining elements of the 'ux' array are set to
> null character values, just the same as 'strncpy' does?
I think 6.7.8p21 (in the N1256 draft) is slightly more applicable. It
says, in part: "If there are ... fewer characters in a string literal
used to initialize an array of known size than there are elements in the
array, the remainder of the aggregate shall be initialized implicitly
the same as objects that have static storage duration."
> I've seen a Microsoft compiler complain about:
>
> void func(void) {
> char foo[100] = {0};
> return;
> }
>
> if the module providing 'memset' was not linked-with. It seems to me
> that for this implementation, initializing with a string literal might
> possibly employ 'strncpy' for the same reason as it employs 'memset' for
> the initialization shown just above.
--
jiw
[toc] | [prev] | [next] | [standalone]
| From | John Gordon <gordon@panix.com> |
|---|---|
| Date | 2011-06-23 22:27 +0000 |
| Message-ID | <iu0el2$clv$1@reader1.panix.com> |
| In reply to | #6755 |
In <iu06d5$cnu$1@speranza.aioe.org> "sumit.sharma" <nospam@nospam.com> writes:
> strncpy(ux.name, "C Language", strlen("C Langage")); /* name is set */
This seems needlessly complicated. Why wouldn't you just do:
strcpy(ux.name, "C Language")
--
John Gordon A is for Amy, who fell down the stairs
gordon@panix.com B is for Basil, assaulted by bears
-- Edward Gorey, "The Gashlycrumb Tinies"
[toc] | [prev] | [next] | [standalone]
| From | Lew Pitcher <lpitcher@teksavvy.com> |
|---|---|
| Date | 2011-06-23 18:47 -0400 |
| Message-ID | <YnPMp.17322$PA5.15790@newsfe01.iad> |
| In reply to | #6755 |
On June 23, 2011 16:07, in comp.lang.c, nospam@nospam.com wrote:
[snip]
> union MyUnion
> {
> char name [100];
> double dblval;
> int intVal;
> };
>
[snip]
>> MyUnion ux;
>
> strncpy(ux.name, "C Language", strlen("C Langage")); /* name is set */
As an aside, the above illustrates a common problem found when programmers
overuse string literals. Here, the strncpy() will result in ux.name being
set to the string array "C Languag", dropping the final "e"
Do you see why? Hint: it has to do with the string literals.
[snip]
--
Lew Pitcher
Master Codewright & JOAT-in-training | Registered Linux User #112576
Me: http://pitcher.digitalfreehold.ca/ | Just Linux: http://justlinux.ca/
---------- Slackware - Because I know what I'm doing. ------
[toc] | [prev] | [next] | [standalone]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2011-06-23 17:54 -0500 |
| Message-ID | <iu0g7a$b58$1@dont-email.me> |
| In reply to | #6767 |
On 6/23/2011 5:47 PM, Lew Pitcher wrote:
> On June 23, 2011 16:07, in comp.lang.c, nospam@nospam.com wrote:
>
> [snip]
>> union MyUnion
>> {
>> char name [100];
>> double dblval;
>> int intVal;
>> };
>>
> [snip]
>>> MyUnion ux;
>>
>> strncpy(ux.name, "C Language", strlen("C Langage")); /* name is set */
>
> As an aside, the above illustrates a common problem found when programmers
> overuse string literals. Here, the strncpy() will result in ux.name being
> set to the string array "C Languag", dropping the final "e"
>
> Do you see why? Hint: it has to do with the string literals.
>
>
> [snip]
>
It also doesn't copy the null terminator, if I'm not mistaken. Since
'ux.name' has a limit, I think using that limit makes some sense.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2011-06-23 17:19 -0700 |
| Message-ID | <lnzkl8dqt2.fsf@nuthaus.mib.org> |
| In reply to | #6768 |
Shao Miller <sha0.miller@gmail.com> writes:
> On 6/23/2011 5:47 PM, Lew Pitcher wrote:
>> On June 23, 2011 16:07, in comp.lang.c, nospam@nospam.com wrote:
>>
>> [snip]
>>> union MyUnion
>>> {
>>> char name [100];
>>> double dblval;
>>> int intVal;
>>> };
>>>
>> [snip]
>>>> MyUnion ux;
>>>
>>> strncpy(ux.name, "C Language", strlen("C Langage")); /* name is set */
>>
>> As an aside, the above illustrates a common problem found when programmers
>> overuse string literals. Here, the strncpy() will result in ux.name being
>> set to the string array "C Languag", dropping the final "e"
>>
>> Do you see why? Hint: it has to do with the string literals.
>> [snip]
>
> It also doesn't copy the null terminator, if I'm not mistaken. Since
> 'ux.name' has a limit, I think using that limit makes some sense.
But since strncpy() pads the destination with nulls, ux.name ends up
containing a valid string (and 91 nulls where 1 would do).
General rule: Don't use strncpy unless you really understand what it
does. (And if you understand what it does, you probably won't want to
use it.)
--
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 | Joe Pfeiffer <pfeiffer@cs.nmsu.edu> |
|---|---|
| Date | 2011-06-23 22:12 -0600 |
| Message-ID | <1bpqm36f6r.fsf@snowball.wb.pfeifferfamily.net> |
| In reply to | #6772 |
Keith Thompson <kst-u@mib.org> writes: <lots snipped> > But since strncpy() pads the destination with nulls, ux.name ends up > containing a valid string (and 91 nulls where 1 would do). > > General rule: Don't use strncpy unless you really understand what it > does. (And if you understand what it does, you probably won't want to > use it.) It really is too bad there isn't a good library function to copy a string safely -- building one on top of memcpy() or even doing it by hand is easy, but it would be better if it were in the library. Is the implementation of snprintf() typically efficient enough to make sense for this purpose?
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2011-06-23 22:32 -0700 |
| Message-ID | <lnsjqzeqvz.fsf@nuthaus.mib.org> |
| In reply to | #6781 |
Joe Pfeiffer <pfeiffer@cs.nmsu.edu> writes:
> Keith Thompson <kst-u@mib.org> writes:
> <lots snipped>
>> But since strncpy() pads the destination with nulls, ux.name ends up
>> containing a valid string (and 91 nulls where 1 would do).
>>
>> General rule: Don't use strncpy unless you really understand what it
>> does. (And if you understand what it does, you probably won't want to
>> use it.)
>
> It really is too bad there isn't a good library function to copy a
> string safely -- building one on top of memcpy() or even doing it by
> hand is easy, but it would be better if it were in the library.
Something like this is pretty close:
#define STRNCPY(dest, src, n) \
(*(dest) = '\0', strncat((dest), (src), (n)))
It evaluates dest twice, but that shouldn't be a problem.
[...]
--
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 | Joe Pfeiffer <pfeiffer@cs.nmsu.edu> |
|---|---|
| Date | 2011-06-24 08:51 -0600 |
| Message-ID | <1boc1n1dv5.fsf@snowball.wb.pfeifferfamily.net> |
| In reply to | #6784 |
Keith Thompson <kst-u@mib.org> writes: > Joe Pfeiffer <pfeiffer@cs.nmsu.edu> writes: >> Keith Thompson <kst-u@mib.org> writes: >> <lots snipped> >>> But since strncpy() pads the destination with nulls, ux.name ends up >>> containing a valid string (and 91 nulls where 1 would do). >>> >>> General rule: Don't use strncpy unless you really understand what it >>> does. (And if you understand what it does, you probably won't want to >>> use it.) >> >> It really is too bad there isn't a good library function to copy a >> string safely -- building one on top of memcpy() or even doing it by >> hand is easy, but it would be better if it were in the library. > > Something like this is pretty close: > > #define STRNCPY(dest, src, n) \ > (*(dest) = '\0', strncat((dest), (src), (n))) > > It evaluates dest twice, but that shouldn't be a problem. Ah, nice. I'll have to remember that...
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2011-06-24 16:30 +0100 |
| Message-ID | <0.b5b39dd51f26cfe8a191.20110624163032BST.877h8b8cx3.fsf@bsb.me.uk> |
| In reply to | #6835 |
Joe Pfeiffer <pfeiffer@cs.nmsu.edu> writes:
> Keith Thompson <kst-u@mib.org> writes:
>
>> Joe Pfeiffer <pfeiffer@cs.nmsu.edu> writes:
>>> Keith Thompson <kst-u@mib.org> writes:
>>> <lots snipped>
>>>> But since strncpy() pads the destination with nulls, ux.name ends up
>>>> containing a valid string (and 91 nulls where 1 would do).
>>>>
>>>> General rule: Don't use strncpy unless you really understand what it
>>>> does. (And if you understand what it does, you probably won't want to
>>>> use it.)
>>>
>>> It really is too bad there isn't a good library function to copy a
>>> string safely -- building one on top of memcpy() or even doing it by
>>> hand is easy, but it would be better if it were in the library.
>>
>> Something like this is pretty close:
>>
>> #define STRNCPY(dest, src, n) \
>> (*(dest) = '\0', strncat((dest), (src), (n)))
>>
>> It evaluates dest twice, but that shouldn't be a problem.
>
> Ah, nice. I'll have to remember that...
I slightly prefer
#define STRNCPY(dest, src, n) strncat(strcpy((dest), ""), (src), (n))
because it does not evaluate dest twice though, as Keith says, that's
not likely to be a problem. Beware, also, of the meaning of n -- you
can't use the size of the destination array since a null character is
added (i.e. n + 1 bytes are written to dest). You might consider:
#define STRNCPY(dest, src, n) \
(n ? strncat(strcpy((dest), ""), (src), (n) - 1) : dest)
if you feel that's more natural. It probably depends on how STRNCPY
will be used. The C library is inconsistent in this regard, but newer
function like snprintf take a size that limits what is written, not how
many non-null characters are written.
<OT>
If C's assignments were like C++'s then once could write:
#define STRNCPY(dest, src, n) strncat(&(*(dest) = '\0'), (src), (n))
and avoid the extra call.
</OT>
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | pete <pfiland@mindspring.com> |
|---|---|
| Date | 2011-06-24 12:46 -0400 |
| Message-ID | <4E04BF7D.F38@mindspring.com> |
| In reply to | #6781 |
Joe Pfeiffer wrote: > It really is too bad there isn't a good library function to copy a > string safely -- C is not all about being able to write good programs without paying attention to what you're doing. It's not difficult to copy a string safely with strcpy. -- pete
[toc] | [prev] | [next] | [standalone]
| From | Joe Pfeiffer <pfeiffer@cs.nmsu.edu> |
|---|---|
| Date | 2011-06-24 16:18 -0600 |
| Message-ID | <1b8vsqvpop.fsf@snowball.wb.pfeifferfamily.net> |
| In reply to | #6845 |
pete <pfiland@mindspring.com> writes: > Joe Pfeiffer wrote: > >> It really is too bad there isn't a good library function to copy a >> string safely -- > > C is not all about > being able to write good programs > without paying attention to what you're doing. > > It's not difficult to copy a string safely with strcpy. Sure -- it's just that it's even easier to do it unsafely. You can do a lot to force programmers to write safe code by banning sprintf(), gets(), strcat(), and the like; you can't get the same effect by banning strcpy().
[toc] | [prev] | [next] | [standalone]
| From | pozz <pozzugno@gmail.com> |
|---|---|
| Date | 2011-06-24 23:14 +0200 |
| Message-ID | <iu2un1$ne7$1@nnrp.ngi.it> |
| In reply to | #6772 |
Il 24/06/2011 02:19, Keith Thompson ha scritto:
> General rule: Don't use strncpy unless you really understand what it
> does. (And if you understand what it does, you probably won't want to
> use it.)
Sorry, but I'm not able to follow your discussion. Why should I avoid
strncpy()?
I have a string buffer defined with a fixed dimension:
char mystring[10];
Now I have to copy an unknown string, maybe passed in as an argument
function, to mystring array. If I use strcpy(), I could write memory
after mystring[].
So I think strncpy() is good to avoid this bad situations:
char mystring[10];
void mystrcpy(const char *arg) {
strncpy(mystring, arg, sizeof(mystring) - 1);
mystring[sizeof(mystring) - 1] = '\0';
}
What is wrong with this?
[toc] | [prev] | [next] | [standalone]
| From | John Gordon <gordon@panix.com> |
|---|---|
| Date | 2011-06-24 21:37 +0000 |
| Message-ID | <iu302q$ms5$1@reader1.panix.com> |
| In reply to | #6885 |
In <iu2un1$ne7$1@nnrp.ngi.it> pozz <pozzugno@gmail.com> writes:
> char mystring[10];
> void mystrcpy(const char *arg) {
> strncpy(mystring, arg, sizeof(mystring) - 1);
> mystring[sizeof(mystring) - 1] = '\0';
> }
A quibble with this particular implementation: Your wrapper function uses
sizeof to get the size of the destination buffer, which a general-purpose
function wouldn't be able to do.
--
John Gordon A is for Amy, who fell down the stairs
gordon@panix.com B is for Basil, assaulted by bears
-- Edward Gorey, "The Gashlycrumb Tinies"
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.c
csiph-web