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


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

Query abt union

Started by"sumit.sharma" <nospam@nospam.com>
First post2011-06-23 20:07 +0000
Last post2011-06-23 17:13 -0600
Articles 20 on this page of 28 — 12 participants

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


Contents

  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 →


#6755 — Query abt union

From"sumit.sharma" <nospam@nospam.com>
Date2011-06-23 20:07 +0000
SubjectQuery 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]


#6757

FromBen Pfaff <blp@cs.stanford.edu>
Date2011-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]


#6764

FromShao Miller <sha0.miller@gmail.com>
Date2011-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]


#6849

FromJames Waldby <not@valid.invalid>
Date2011-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]


#6855

FromShao Miller <sha0.miller@gmail.com>
Date2011-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]


#6884

FromJames Waldby <not@valid.invalid>
Date2011-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]


#6979

FromShao Miller <sha0.miller@gmail.com>
Date2011-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]


#7021

FromJames Waldby <not@valid.invalid>
Date2011-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]


#6765

FromJohn Gordon <gordon@panix.com>
Date2011-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]


#6767

FromLew Pitcher <lpitcher@teksavvy.com>
Date2011-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]


#6768

FromShao Miller <sha0.miller@gmail.com>
Date2011-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]


#6772

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


#6781

FromJoe Pfeiffer <pfeiffer@cs.nmsu.edu>
Date2011-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]


#6784

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


#6835

FromJoe Pfeiffer <pfeiffer@cs.nmsu.edu>
Date2011-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]


#6839

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


#6845

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


#6903

FromJoe Pfeiffer <pfeiffer@cs.nmsu.edu>
Date2011-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]


#6885

Frompozz <pozzugno@gmail.com>
Date2011-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]


#6892

FromJohn Gordon <gordon@panix.com>
Date2011-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