Thread: Question related to NULL assignment in pointers to structs

  1. #1
    Registered User
    Join Date
    Mar 2023
    Posts
    33

    Question related to NULL assignment in pointers to structs

    Let's say we have this code under the pe-processor directives, as if we were going to create a linked list:

    Code:
    struct node
    {
      int value;
      struct node *next;
    };
    
    struct node *first = NULL; 
    struct node *current = NULL; 
    struct node *previous = NULL;
    The assignment here doesn't appear to be necessary, as I've tested pointers to struct without the NULL assignment, and when you make the linked list...the next pointer is NULL by default. This appears to be true for both gcc and clang.

    However, in the interest of preventing un-defined behavior...does assigning NULL like that to those 3 pointers mean the next pointer inside of them is also NULL?

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by C_me_run
    The assignment here doesn't appear to be necessary, as I've tested pointers to struct without the NULL assignment
    That's initialisation, not assignment. The key here is that you have declared these variables outside of a function, so they have static storage duration (this is true even though the static keyword was not used; if you did use it, they would still have static storage duration, but would have internal linkage instead of the external linkage that they have now), and are initialised at startup. If you don't specify any constant for initialisation, they are zero initialised, which for pointers means that they are initialised to be null pointers.

    Quote Originally Posted by C_me_run
    and when you make the linked list...the next pointer is NULL by default.
    How are you making the linked list?

    Quote Originally Posted by C_me_run
    However, in the interest of preventing un-defined behavior...does assigning NULL like that to those 3 pointers mean the next pointer inside of them is also NULL?
    It doesn't, because there is no next pointer inside of them. They are pointers to struct node objects, but not struct node objects themselves, thus they don't have any members, hence they don't have a next pointer member.
    Quote 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.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Dec 2023
    Posts
    2
    Here are step-by-step ANSI C citations to confirm the explicit NULL assignments aren’t required.


    3.1.2,1 Scopes of Identifiers
    “If the declarator or type specifier that declares the identifier appears outside of any block or list of parameters, the identifier has file scope, which terminates at the end of the translation unit. If the declarator or type specifier that declares the identifier appears inside a block or within the list of parameter declarations in a function definition, the identifier has block scope, which terminates at the } that closes the associated block.”


    These struct declarations aren't within a block, so they have file scope.


    3.1.2.2 Linkages of Identifiers
    “If the declaration of an identifier for an object has file scope and no storage-class specifier, its linkage is external.”


    These file-scoped struct definitions have external linkage.


    3.1.2.4 Storage Durations of Objects
    “An object whose identifier is declared with external or internal linkage, or with the storage class specifier static has static storage duration.”


    These file-scoped, externally-linked struct definitions have static storage duration.


    3.5.7 Initialization -> Semantics
    “If an object that has static storage duration is not initialized explicitly, it is initialized implicitly as if every member that has arithmetic type were assigned 0 and every member that has pointer type were assigned a null pointer constant.”


    These file-scoped, externally-linked struct definitions with non-explicit static storage duration are initialized with NULL.

  4. #4
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    1,111
    Quote Originally Posted by entrocraft View Post
    Here are step-by-step ANSI C citations to confirm the explicit NULL assignments aren’t required.
    ...
    What document are you quoting? Even in the C90 Standard RFC, the sections are:
    6.1.2.1 Scopes of identifiers
    6.1.2.2 Linkages of identifiers
    ...
    You should be quoting the latest C18 Standard,

  5. #5
    Registered User
    Join Date
    Dec 2017
    Posts
    1,633
    Yeah, he's referring to the initial ANSI C standard (aka C89 or C90).
    https://web.archive.org/web/20161223....uk/ansi.c.txt

    Isn't the current standard called C17 (not C18)?
    C (programming language) - Wikipedia

    What you've posted is referred to as "C2x working draft" here:
    WG 14 Document log

    This seems to be the closest to the final draft of C17:
    https://www.open-std.org/jtc1/sc22/w...docs/n2176.pdf

    Working draft of C23 (coming in 2024?) here:
    https://www.open-std.org/jtc1/sc22/w...docs/n3096.pdf
    A little inaccuracy saves tons of explanation. - H.H. Munro

  6. #6
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    1,111
    Yes, he was probably using a copy of C89 (ANSI) not C90 (ISO)

    At some point, I did see C17 listed on an ISO page as C18, and really should be called C18 as it was adopted in 2018:
    "C17 ISO/IEC 9899:2018"

    Which breaks the naming convention of C90, C99, and C11.

    This file is password protected:
    This seems to be the closest to the final draft of C17:
    https://www.open-std.org/jtc1/sc22/w...docs/n2176.pdf
    Last edited by Salem; 12-10-2023 at 06:07 AM. Reason: Fixed URL

  7. #7
    Registered User
    Join Date
    Mar 2023
    Posts
    33
    Quote Originally Posted by laserlight View Post
    That's initialisation, not assignment.
    It's initialization and assignment, unless "=" is not an assignment operator (and yes it is)

    If you don't specify any constant for initialisation, they are zero initialised, which for pointers means that they are initialised to be null pointers.


    No, actually this is not true at all. Let me prove it:

    Code:
    #include<stdio.h>
    int main()
    {
      int *value;
    
    
      if(!value)
      {
        printf("it's a NULL pointer!\n");
      }
      else
      {
        puts("it's not a NULL pointer\n");
      }
    
    
      return 0;
    }
    Here's the output:

    it's not a NULL pointer


    And that's the reason I posted this anyway: it seems that the pointer inside of the struct is NULL when I allocate memory for it.





    Last edited by C_me_run; 12-08-2023 at 08:49 PM.

  8. #8
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    1,111
    Global variables, defined outside of any function, not explicitly initialized, are automatically initialized to zero or NULL in the case of pointers.

    Local variables, defined inside of a function, are NOT initialized, and pickup whatever garbage value is in memory when the function is called.

    You should initialize ALL local variables!!! Explicitly initializing ALL variables is always a god idea, especially pointers!

    Example:
    Code:
    #include <stdio.h>
    
    char *ptr1;  // Global automatically initialized to NULL
    
    int main(void)
    {
      char *ptr2;  // Local NOT initialized!
      
      printf("ptr1 == %p\n", (void *)ptr1);
      printf("ptr2 == %p\n", (void *)ptr2);
      
      return 0;
    }
    Code:
    Output:
    
    ptr1 == (nil)
    ptr2 == 0x7fdbdf952ab0
    Last edited by rstanley; 12-08-2023 at 09:45 PM.

  9. #9
    Registered User
    Join Date
    Mar 2023
    Posts
    33
    Quote Originally Posted by rstanley View Post
    Global variables, defined outside of any function, not explicitly initialized, are automatically initialized to zero or NULL in the case of pointers.

    Local variables, defined inside of a function, are NOT initialized, and pickup whatever garbage value is in memory when the function is called.

    You should initialize ALL local variables!!! Explicitly initializing ALL variables is always a god idea, especially pointers!

    Example:
    Code:
    #include <stdio.h>
    
    char *ptr1;  // Global automatically initialized to NULL
    
    int main(void)
    {
      char *ptr2;  // Local NOT initialized!
      
      printf("ptr1 == %p\n", (void *)ptr1);
      printf("ptr2 == %p\n", (void *)ptr2);
      
      return 0;
    }
    Code:
    Output:
    
    ptr1 == (nil)
    ptr2 == 0x7fdbdf952ab0
    Thanks for clarifying that, i believe that's what laserlight was saying but i was distracted by the other terminology.

  10. #10
    Registered User
    Join Date
    Dec 2017
    Posts
    1,633
    Non-password protected version of C17 draft:
    https://web.archive.org/web/20181230...posed_fdis.pdf
    I don't know where you got the 404 from (or how you knew it was password protected if you got a 404).
    A little inaccuracy saves tons of explanation. - H.H. Munro

  11. #11
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    1,111
    Quote Originally Posted by john.c View Post
    Non-password protected version of C17 draft:
    https://web.archive.org/web/20181230...posed_fdis.pdf
    I don't know where you got the 404 from (or how you knew it was password protected if you got a 404).
    I just clicked on the link and it asked for a password to open the PDF file. No 404.

  12. #12
    Registered User
    Join Date
    Mar 2023
    Posts
    33
    Quote Originally Posted by rstanley View Post
    Yes, he was probably using a copy of C89 (ANSI) not C90 (ISO)

    At some point, I did see C17 listed on an ISO page as C18, and really should be called C18 as it was adopted in 2018:
    "C17 ISO/IEC 9899:2018"

    Which breaks the naming convention of C90, C99, and C11.

    This file is password protected:
    I didn't get that error, oh well, the internet is strange.

  13. #13
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by C_me_run
    It's initialization and assignment, unless "=" is not an assignment operator (and yes it is)
    No, in this context "=" is not the assignment operator. While initialisation certainly involves assignment in the computer science sense, C distinguishes between initialisation and assignment, that's why I noted that "that's initialisation, not assignment". I did not mean to imply that there was no assignment of value, because of course initialisation involves the initial assignment of a value.

    Quote Originally Posted by C_me_run
    No, actually this is not true at all. Let me prove it:
    Good to see that rstanley cleared it up, though you must have missed my preceding sentence about static storage duration because "you have declared these variables outside of a function" and how that means that those variables are "are initialised at startup".

    Quote Originally Posted by rstanley
    Explicitly initializing ALL variables is always a god idea, especially pointers!
    Ascribing divinity might be taking it a step too far, but I suppose it works!
    Last edited by laserlight; 12-11-2023 at 12:23 AM.
    Quote 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.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  14. #14
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    1,111
    Originally Posted by rstanley
    Explicitly initializing ALL variables is always a god idea, especially pointers!
    Ascribing divinity might be taking it a step too far, but I suppose it works!
    Typo, obviously! "Good" not "god"! ;^)

    Although, some programmers do think C is a religion! ;^)

  15. #15
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    Quote Originally Posted by rstanley View Post
    Typo, obviously! "Good" not "god"! ;^)

    Although, some programmers do think C is a religion! ;^)
    No; But, I think "spaces" versus "tabs" is a religious split.

    Tim S.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Another pointers / struct/ array related question
    By patishi in forum C Programming
    Replies: 3
    Last Post: 09-11-2013, 05:25 PM
  2. a question on pointers, structs and arrays
    By onefootswill in forum C Programming
    Replies: 3
    Last Post: 12-06-2007, 01:27 AM
  3. A question on Pointers & Structs
    By FJ8II in forum C++ Programming
    Replies: 4
    Last Post: 05-28-2007, 10:56 PM
  4. Question related to array and pointers
    By Q4u in forum C++ Programming
    Replies: 6
    Last Post: 07-26-2002, 12:54 PM
  5. Pointers Question.....Null Pointers!!!!
    By incognito in forum C++ Programming
    Replies: 5
    Last Post: 12-28-2001, 11:13 PM

Tags for this Thread