Ansi C++ Struct Assignment

  1. Registered User
    Join Date
    Oct 2012
    Location
    Southampton, United Kingdom.
    Posts
    18

    assign null value to a struct and check if it is null

    Hi everyone,

    I want to initialize my struct with a null value, and at some point check whether the struct is null.

    struct mystruct s = {0};
    and then when i need to check it:
    if(s == {0}) then do something
    but it doesn't seem to be the right way of doing it.

    Any help?

    Thanks in advance.

  2. C++ Witch
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    25,792
    Look up a C++ Reference and learn How To Ask Questions The Smart Way
    Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Perhaps you want to create a pointer to an object of your struct type, then initialise it to be a null pointer?

    Otherwise, you simply have to define what it means for your struct to be "null", do so, and thus it shall be "null".

  3. Registered User
    Join Date
    Sep 2012
    Posts
    357
    Last edited by qny; 10-30-2012 at 10:08 AM. Reason: wrong code
    Wrong code below. Please ignore.
    I just keep it here because there have been comments based on it.

    struct mystruct s = {0}, snull = {0}; /* possibly change s */ /* WRONG CODE BELOW, SORRY */ if (s == snull) { /* do something */ }

  4. Registered User
    Join Date
    Oct 2012
    Location
    Southampton, United Kingdom.
    Posts
    18
    Hi qny,

    When I tried to do that, it gave me "invalid operand to binary ==" error..

  5. C++ Witch
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    25,792
    Look up a C++ Reference and learn How To Ask Questions The Smart Way
    Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Just compare the members of the struct with 0. The use of memcmp may be an appropriate alternative. As I said, if you really do want to talk about a "null" struct, then you need to define precisely what that means. As yet, you have not even shown us your struct definition.

  6. Registered User
    Join Date
    Sep 2012
    Posts
    357
    Oops, my bad. Sorry.
    You need to compare member by member (for those members that are comparable)
    if ((s.member1 == snull.member1) && (s.member2 == snull.member2) && /* ... */ (s.memberN == snull.memberN)) { /* do something */ }
    Originally Posted by ymc1g11
    Hi qny,

    When I tried to do that, it gave me "invalid operand to binary ==" error..

  7. Registered User
    Join Date
    Oct 2012
    Location
    Southampton, United Kingdom.
    Posts
    18
    laserlight,

    here's the struct i created:
    struct tnode { char *word; int count; struct tnode *left; struct tnode *right; };
    I am trying to implement it as a tree. So, to do that, I initialized the root of the tree as NULL as follows:
    struct tnode root = {0};
    So every time when I add an element(which is a char*), it will check if the current node is null, add the element to root if yes, else traverse the tree recursively.

    Much thanks in advance
    Originally Posted by laserlight
    Just compare the members of the struct with 0. The use of memcmp may be an appropriate alternative. As I said, if you really do want to talk about a "null" struct, then you need to define precisely what that means. As yet, you have not even shown us your struct definition.

  8. C++ Witch
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    25,792
    Look up a C++ Reference and learn How To Ask Questions The Smart Way
    Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    The thing is, the root is not "null". It is zero initialised.

    It might make more sense to have root be a pointer instead. If you do want it to be a struct tnode object, then you can either compare its members with 0, or just the word member.

  9. Algorithm Dissector
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"
    root should be a pointer just like left and right are. Anything else would honestly be a mistake.

  10. Registered User
    Join Date
    Oct 2012
    Location
    Southampton, United Kingdom.
    Posts
    18
    sorry i just cant get my head round it as a beginner

    so i should declare it in my main as this:
    struct tnode *root;
    and in my method sort,
    -how do i check if the 'root' had been assigned anything?
    -do i need to first declare the 'root' is empty?

    this is my method which sort words into the tree (made of struct tnode):
    voidsort(struct tnode **r, char *w){if(r == null){ r = (struct tnode *) malloc(sizeof(struct tnode)); r->word = w; r->count = 1; r->*left = null; r->*right = null; (printf("%s\n", r->word)); }else{int cmp = strcmp(w, r->word); if(cmp<0){ sort(r->left, w); }elseif(cmp>0){ sort(r->right, w); }else r->count++; } }
    Please help~ and much thanks~!
    Originally Posted by laserlight
    The thing is, the root is not "null". It is zero initialised.

    It might make more sense to have root be a pointer instead. If you do want it to be a struct tnode object, then you can either compare its members with 0, or just the word member.

  11. Registered User
    Join Date
    Oct 2012
    Location
    Southampton, United Kingdom.
    Posts
    18
    sorted! cheers!


When initializing an object of struct or union type, the initializer must be a non-empty, brace-enclosed, comma-separated list of initializers for the members:

expression(until C99)
designator(optional)expression(since C99)

where the designator is a sequence (whitespace-separated or adjacent) of individual member designators of the form member and array designators of the form index.

All members that are not initialized explicitly are initialized implicitly the same way as objects that have static storage duration.

[edit]Explanation

When initializing a union, the initializer list must have only one member, which initializes the first member of the union unless a designated initializer is used(since C99).

When initializing a struct, the first initializer in the list initializes the first declared member (unless a designator is specified)(since C99), and all subsequent initializers without designators (since C99)initialize the struct members declared after the one initialized by the previous expression.

A designator causes the following initializer to initialize the struct member described by the designator. Initialization then continues forward in order of declaration, beginning with the next element declared after the one described by the designator.

struct{int sec,min,hour,day,mon,year;} z ={.day=31,12,2014,.sec=30,15,17};// initializes z to {30,15,17,31,12,2014}
(since C99)

It's an error to provide more initializers than members.

[edit]Nested initialization

If the members of the struct or union are arrays, structs, or unions, the corresponding initializers in the brace-enclosed list of initializers are any initializers that are valid for those members, except that their braces may be omitted as follows:

If the nested initializer begins with an opening brace, the entire nested initializer up to its closing brace initializes the corresponding member object. Each left opening brace establishes a new current object. The members of the current object are initialized in their natural order, unless designators are used(since C99): array elements in subscript order, struct members in declaration order, only the first declared member of any union. The subobjects within the current object that aren't explicitly initialized by the closing brace are implicitly initialized.

If the nested initializer does not begin with an opening brace, only enough initializers from the list are taken to account for the elements or members of the member array, struct or union; any remaining initializers are left to initialize the next struct member:

When designators are nested, the designators for the members follow the designators for the enclosing structs/unions/arrays. Within any nested bracketed initializer list, the outermost designator refers to the current object and selects the subobject to be initialized within the current object only.

If any subobject is explicitly initialized twice (which may happen when designators are used), the initializer that appears later in the list is the one used (the earlier initializer may not be evaluated):

Although any non-initialized subobjects are initialized implicitly, implicit initialization of a subobject never overrides explicit initialization of the same subobject if it appeared earlier in the initializer list:

Run this code

Output:

#include <stdio.h>typedefstruct{int k;int l;int a[2];} T;typedefstruct{int i; T t;} S; T x ={.l=43, .k=42, .a[1]=19, .a[0]=18};// x initialized to {42, 43, {18, 19} }int main(void){ S l ={1, // initializes l.i to 1 .t= x, // initializes l.t to {42, 43, {18, 19} } .t.l=41, // changes l.t to {42, 41, {18, 19} } .t.a[1]=17// changes l.t to {42, 41, {18, 17} }};printf("l.t.k is %d\n", l.t.k);// .t = x sets l.t.k to 42 explicitly// .t.l = 42 would zero out l.t.k implicitly}

However, when an initializer begins with a left open brace, its current object is fully re-initialized and any prior explicit initializers for any of its subobjects are ignored:

struct example ex2 ={// current object is ex2, designators are for members of example .in_u.a8[0]=127, 0, 0, 1, .addr=80};struct example ex3 ={80, .in_u={// changes current object to the union ex.in_u127, .a8[2]=1// this designator refers to the member of in_u}};
struct{int n;} s ={printf("a\n"), // this may be printed or skipped .n=printf("b\n")};// always printed
struct fred {char s[4];int n;};struct fred x[]={{{"abc"}, 1}, // inits x[0] to { {'a','b','c','\0'}, 1 }[0].s[0]='q'// changes x[0] to { {'q','b','c','\0'}, 1 }};struct fred y[]={{{"abc"}, 1}, // inits y[0] to { {'a','b','c','\0'}, 1 }[0]={// current object is now the entire y[0] object .s[0]='q'}// replaces y[0] with { {'q','\0','\0','\0'}, 0 }};
(since C99)

[edit]Notes

The order of evaluation of the subexpressions in any initializer is indeterminately sequenced:

In C, the braced list of initializers cannot be empty (note that C++ allows empty lists, and also note that a struct in C cannot be empty):

As with all other initialization, every expression in the initializer list must be a constant expression when initializing arrays of static or thread-local storage duration:

The initializer list may have a trailing comma, which is ignored.

[edit]Example

Run this code

Possible output:

#include <stdio.h>#include <time.h>   int main(void){char buff[70];// designated initalizers simplify the use of structs whose// order of members is unspecifiedstructtm my_time ={ .tm_year=112, .tm_mon=9, .tm_mday=9, .tm_hour=8, .tm_min=10, .tm_sec=20};strftime(buff, sizeof buff, "%A %c", &my_time);puts(buff);}
Sunday Sun Oct 9 08:10:20 2012

[edit]References

  • C11 standard (ISO/IEC 9899:2011):
  • 6.7.9/12-38 Initialization (p: 140-144)
  • C99 standard (ISO/IEC 9899:1999):
  • 6.7.8/12-38 Initialization (p: 126-130)
  • C89/C90 standard (ISO/IEC 9899:1990):

[edit]See also

union{int x;char c[4];} u ={1}, // makes u.x active with value 1 u2 ={ .c={'\1'}};// makes u2.c active with value {'\1','\0','\0','\0'}
struct point {double x,y,z;} p ={1.2, 1.3};// p.x=1.2, p.y=1.3, p.z=0.0 div_t answer ={.quot=2, .rem=-1};// order of elements in div_t may vary
struct example {struct addr_t {uint32_t port;} addr;union{uint8_t a8[4];uint16_t a16[2];} in_u;};struct example ex ={// start of initializer list for struct example{// start of initializer list for ex.addr80// initialized struct's only member}, // end of initializer list for ex.addr{// start of initializer-list for ex.in_u{127,0,0,1}// initializes first element of the union}};
struct example ex ={80, 127, 0, 0, 1};// 80 initializes ex.addr.port// 127 initializes ex.in_u.a8[0]// 0 initializes ex.in_u.a8[1]// 0 initializes ex.in_u.a8[2]// 1 initializes ex.in_u.a8[3]
int n =1;struct{int x,y;} p ={n++, n++};// unspecified, but well-defined behavior:// n is incremented twice in arbitrary order// p equal {1,2} and {2,1} are both valid
struct{int n;} s ={0};// OKstruct{int n;} s ={};// Error: initializer-list cannot be emptystruct{} s ={};// Error: struct cannot be empty, initializer-list cannot be empty
staticstruct{char* p} s ={malloc(1)};// error
struct{double x,y;} p ={1.0, 2.0, // trailing comma OK};

0 thoughts on “Ansi C++ Struct Assignment

Leave a Reply

Your email address will not be published. Required fields are marked *