Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. The Lounge
  3. C declarations are half backward

C declarations are half backward

Scheduled Pinned Locked Moved The Lounge
data-structuresquestion
57 Posts 25 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • H honey the codewitch

    Does it bother anyone else that you declare a pointer like:

    char* sz; // pointer type, pointer declared *with* type

    But an array is declared like this:

    char sz[1024];// array type, array declared *after* var name

    I think it's inconsistent, and I think the array specifier should have been declared with the type since it's essentially a type modifier like * and & Maybe it's just me?

    Real programmers use butterflies

    D Offline
    D Offline
    Daniel Pfeffer
    wrote on last edited by
    #6

    They are literally half backward. In order to understand a C type definition, you ping-pong between the part before the name and the part after, until all tokens have been processed. X| If there is one single thing for K&R ought to have been taken out and shot, this is it! :|

    Freedom is the freedom to say that two plus two make four. If that is granted, all else follows. -- 6079 Smith W.

    1 Reply Last reply
    0
    • H honey the codewitch

      Does it bother anyone else that you declare a pointer like:

      char* sz; // pointer type, pointer declared *with* type

      But an array is declared like this:

      char sz[1024];// array type, array declared *after* var name

      I think it's inconsistent, and I think the array specifier should have been declared with the type since it's essentially a type modifier like * and & Maybe it's just me?

      Real programmers use butterflies

      R Offline
      R Offline
      RickZeeland
      wrote on last edited by
      #7

      Let it Rust! :-\

      1 Reply Last reply
      0
      • H honey the codewitch

        Does it bother anyone else that you declare a pointer like:

        char* sz; // pointer type, pointer declared *with* type

        But an array is declared like this:

        char sz[1024];// array type, array declared *after* var name

        I think it's inconsistent, and I think the array specifier should have been declared with the type since it's essentially a type modifier like * and & Maybe it's just me?

        Real programmers use butterflies

        OriginalGriffO Offline
        OriginalGriffO Offline
        OriginalGriff
        wrote on last edited by
        #8

        The usage is odd as well:

        char* p = ...
        *p = 'x';

        Vs

        foo f;
        foo *pf = &f;
        f.x = '?';
        pf->x = '!';

        Why invent two access operators "." and "->", when you could just use "*pf.x" and be more consistent? Or use "->" to dereference all pointers? I get the feeling bits of the C spec were thrown in just before the submission deadline ... :laugh:

        "I have no idea what I did, but I'm taking full credit for it." - ThisOldTony "Common sense is so rare these days, it should be classified as a super power" - Random T-shirt AntiTwitter: @DalekDave is now a follower!

        "I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
        "Common sense is so rare these days, it should be classified as a super power" - Random T-shirt

        D M 2 Replies Last reply
        0
        • OriginalGriffO OriginalGriff

          The usage is odd as well:

          char* p = ...
          *p = 'x';

          Vs

          foo f;
          foo *pf = &f;
          f.x = '?';
          pf->x = '!';

          Why invent two access operators "." and "->", when you could just use "*pf.x" and be more consistent? Or use "->" to dereference all pointers? I get the feeling bits of the C spec were thrown in just before the submission deadline ... :laugh:

          "I have no idea what I did, but I'm taking full credit for it." - ThisOldTony "Common sense is so rare these days, it should be classified as a super power" - Random T-shirt AntiTwitter: @DalekDave is now a follower!

          D Offline
          D Offline
          Daniel Pfeffer
          wrote on last edited by
          #9

          Quote:

          Why do we do this? I'll tell you... I don't know. But because of this, every one of us knows what a pointer is, how to dereference it, and what K&R expect of him.

          With apologies to Sholem Aleichem and to the producers of Fiddler on the Roof :)

          Freedom is the freedom to say that two plus two make four. If that is granted, all else follows. -- 6079 Smith W.

          W 1 Reply Last reply
          0
          • H honey the codewitch

            Does it bother anyone else that you declare a pointer like:

            char* sz; // pointer type, pointer declared *with* type

            But an array is declared like this:

            char sz[1024];// array type, array declared *after* var name

            I think it's inconsistent, and I think the array specifier should have been declared with the type since it's essentially a type modifier like * and & Maybe it's just me?

            Real programmers use butterflies

            L Offline
            L Offline
            Lost User
            wrote on last edited by
            #10

            If you read it in reverse it can make more sense:

            // extra space before asterisk for readability (I never use it)
            char * sz; // sz is a pointer to a character variable

            char sz[1024]; // sz is an array of character types

            H V 2 Replies Last reply
            0
            • S swampwiz

              What has bothered me more is the fact that: int* pa; int *pa; are the same. Had I been Bjorn, I wouldn't have allowed the latter.

              L Offline
              L Offline
              Lost User
              wrote on last edited by
              #11

              But you can also write:

              int*pa;
              int * pa;

              the spaces do not affect the binding. And that was the rule way before the great Stroustrup.

              1 Reply Last reply
              0
              • H honey the codewitch

                Does it bother anyone else that you declare a pointer like:

                char* sz; // pointer type, pointer declared *with* type

                But an array is declared like this:

                char sz[1024];// array type, array declared *after* var name

                I think it's inconsistent, and I think the array specifier should have been declared with the type since it's essentially a type modifier like * and & Maybe it's just me?

                Real programmers use butterflies

                Sander RosselS Offline
                Sander RosselS Offline
                Sander Rossel
                wrote on last edited by
                #12

                char* means you should read the footnote. * array declarations in C may or may not be consistent.

                Best, Sander Azure DevOps Succinctly (free eBook) Azure Serverless Succinctly (free eBook) Migrating Apps to the Cloud with Azure arrgh.js - Bringing LINQ to JavaScript

                1 Reply Last reply
                0
                • L Lost User

                  If you read it in reverse it can make more sense:

                  // extra space before asterisk for readability (I never use it)
                  char * sz; // sz is a pointer to a character variable

                  char sz[1024]; // sz is an array of character types

                  H Offline
                  H Offline
                  honey the codewitch
                  wrote on last edited by
                  #13

                  The floating asterisk looks lonely!

                  Real programmers use butterflies

                  1 Reply Last reply
                  0
                  • H honey the codewitch

                    Does it bother anyone else that you declare a pointer like:

                    char* sz; // pointer type, pointer declared *with* type

                    But an array is declared like this:

                    char sz[1024];// array type, array declared *after* var name

                    I think it's inconsistent, and I think the array specifier should have been declared with the type since it's essentially a type modifier like * and & Maybe it's just me?

                    Real programmers use butterflies

                    V Offline
                    V Offline
                    Vikram A Punathambekar
                    wrote on last edited by
                    #14

                    I wrote this in a previous life: [How to interpret complex C/C++ declarations](https://www.codeproject.com/Articles/7042/How-to-interpret-complex-C-C-declarations)

                    Cheers, विक्रम "We have already been through this, I am not going to repeat myself." - fat_boy, in a global warming thread :doh:

                    1 Reply Last reply
                    0
                    • L Lost User

                      If you read it in reverse it can make more sense:

                      // extra space before asterisk for readability (I never use it)
                      char * sz; // sz is a pointer to a character variable

                      char sz[1024]; // sz is an array of character types

                      V Offline
                      V Offline
                      Vikram A Punathambekar
                      wrote on last edited by
                      #15

                      There's a stricter formal rule, called the Right-Left rule. I wrote my only technical article on CP more than 15 years back on just this: [How to interpret complex C/C++ declarations](https://www.codeproject.com/Articles/7042/How-to-interpret-complex-C-C-declarations)

                      Cheers, विक्रम "We have already been through this, I am not going to repeat myself." - fat_boy, in a global warming thread :doh:

                      L 1 Reply Last reply
                      0
                      • V Vikram A Punathambekar

                        There's a stricter formal rule, called the Right-Left rule. I wrote my only technical article on CP more than 15 years back on just this: [How to interpret complex C/C++ declarations](https://www.codeproject.com/Articles/7042/How-to-interpret-complex-C-C-declarations)

                        Cheers, विक्रम "We have already been through this, I am not going to repeat myself." - fat_boy, in a global warming thread :doh:

                        L Offline
                        L Offline
                        Lost User
                        wrote on last edited by
                        #16

                        Yes, but I could not remember it. I know it's important when typedef'ing function pointers. I just reread your article - very interesting, and should be required reading for all the QA kiddies.

                        1 Reply Last reply
                        0
                        • S swampwiz

                          What has bothered me more is the fact that: int* pa; int *pa; are the same. Had I been Bjorn, I wouldn't have allowed the latter.

                          Mike HankeyM Offline
                          Mike HankeyM Offline
                          Mike Hankey
                          wrote on last edited by
                          #17

                          Agree, the later makes no sense.

                          I'm not sure how many cookies it makes to be happy, but so far it's not 27. JaxCoder.com

                          1 Reply Last reply
                          0
                          • H honey the codewitch

                            Does it bother anyone else that you declare a pointer like:

                            char* sz; // pointer type, pointer declared *with* type

                            But an array is declared like this:

                            char sz[1024];// array type, array declared *after* var name

                            I think it's inconsistent, and I think the array specifier should have been declared with the type since it's essentially a type modifier like * and & Maybe it's just me?

                            Real programmers use butterflies

                            P Offline
                            P Offline
                            PIEBALDconsult
                            wrote on last edited by
                            #18

                            And?

                            1 Reply Last reply
                            0
                            • H honey the codewitch

                              Does it bother anyone else that you declare a pointer like:

                              char* sz; // pointer type, pointer declared *with* type

                              But an array is declared like this:

                              char sz[1024];// array type, array declared *after* var name

                              I think it's inconsistent, and I think the array specifier should have been declared with the type since it's essentially a type modifier like * and & Maybe it's just me?

                              Real programmers use butterflies

                              T Offline
                              T Offline
                              theoldfool
                              wrote on last edited by
                              #19

                              Stop whining. :) Declarations made easy. Computer Language Magazine, May, 1991.

                              If you can keep your head while those about you are losing theirs, perhaps you don't understand the situation.

                              1 Reply Last reply
                              0
                              • H honey the codewitch

                                Does it bother anyone else that you declare a pointer like:

                                char* sz; // pointer type, pointer declared *with* type

                                But an array is declared like this:

                                char sz[1024];// array type, array declared *after* var name

                                I think it's inconsistent, and I think the array specifier should have been declared with the type since it's essentially a type modifier like * and & Maybe it's just me?

                                Real programmers use butterflies

                                M Offline
                                M Offline
                                Mike Winiberg
                                wrote on last edited by
                                #20

                                Without wishing to start a major language debate, I think its important to understand that C was designed to be efficient at using the underlying hardware of the machine, and the way things are declared reflects this: char *sz declares a single variable that points to a place in memory, supposedly holding a char value. This pointer (and here's where dragons lie!) can be made to point to anywhere and to anything regardless of its declaration, you are just telling the compiler that at the place where that pointer points, YOU consider there to be a char value (whether it is or not in reality). char sz[1024] says that at the address represented by sz is a reserved block of memory that holds (in theory) 1024 char items. In your code you can (with some severe caveats!) use both variables in the same way and it's up to you to remember and manage whatever you think you are looking at in that location - this is both the beauty and danger of a language like C - it allows you to manipulate things in much the same way as in assembler and with as few restrictions, but it provides no protection against you doing something stupid. However, even the early compilers would detect if you attempted to treat these two variables as exactly equivalent, but would often only warn rather than prevent it, allowing you to create absolute havoc. Much code rot is caused by the developer incorrectly assuming that, by default, either of these variables is initialised (which is why most compilers these days will attempt to put something sensible in newly declared variables to protect the innocent). Before initialisation char *sz may contain a random address and even attempting to look at it might cause a total system crash if it accidentally points into hardware protected memory. With char sz[1024] though you can be sure that doing char x = *sz is safe because sz already holds a valid address and points into memory allocated to your program, what you don't know is what value you will actually get back from that place before the array is initialised. Why have I bored you all with this stuff? Because so many developers these days seem to know absolutely nothing at all about how the hardware they are driving works - that's fine if you are writing in a high-level domain specific language where everything like that is hidden - no help at all if you are writing a device driver for some complex piece of hardware that is integrated into an operating system of some sort.

                                H W 2 Replies Last reply
                                0
                                • H honey the codewitch

                                  Does it bother anyone else that you declare a pointer like:

                                  char* sz; // pointer type, pointer declared *with* type

                                  But an array is declared like this:

                                  char sz[1024];// array type, array declared *after* var name

                                  I think it's inconsistent, and I think the array specifier should have been declared with the type since it's essentially a type modifier like * and & Maybe it's just me?

                                  Real programmers use butterflies

                                  J Offline
                                  J Offline
                                  Joop Eggen
                                  wrote on last edited by
                                  #21

                                  Java's stupid (=political) C compatibility C started as a simple language on top of assembly language. Lingual considerations of abstractional consistency had no priority. As error awareness. Everything is an int, boolean, pointer, array, functions. In fact declarations have a weird kind of syntax requiring a large parsing. Or for a human a bit of back-and-forth reading. As java was launched, it intended to improve some parts of C++/C. So in java the entire type info becomes separate from the variable.

                                  char[] jarr; // Normal java.

                                  But as novice java kept the C style for accustomed C/C++ programmmers:

                                  char jarr[]; // Obsolete C style java.

                                  If one looks at java's:

                                  char[] jarr = new char[1024];

                                  one get's an idea why C chose:

                                  char str[1024];

                                  The 1024 is not part of the `char*` data structure as field, but some compile time allocation. In general one should accept C as it is: a compiler strong, thin layered, fun language. For language features it is pedagogical unsuited w.r.t. type systems, actual data, error prevention and so on. Taking any language, like a simple Pascal, might give less confusion with pointer versus array like in parameter passing. Then going back to C one sees that arrays are passed as pointers i.o. the pointed-to data as in Pascal.

                                  1 Reply Last reply
                                  0
                                  • H honey the codewitch

                                    Does it bother anyone else that you declare a pointer like:

                                    char* sz; // pointer type, pointer declared *with* type

                                    But an array is declared like this:

                                    char sz[1024];// array type, array declared *after* var name

                                    I think it's inconsistent, and I think the array specifier should have been declared with the type since it's essentially a type modifier like * and & Maybe it's just me?

                                    Real programmers use butterflies

                                    R Offline
                                    R Offline
                                    Rusty Bullet
                                    wrote on last edited by
                                    #22

                                    When I was learning C, it bothered and confused me. Now, I recognized it as the type and it doesn't bother me. Is that age, tolerance, or just exposure to too many languages???

                                    H 1 Reply Last reply
                                    0
                                    • R Rusty Bullet

                                      When I was learning C, it bothered and confused me. Now, I recognized it as the type and it doesn't bother me. Is that age, tolerance, or just exposure to too many languages???

                                      H Offline
                                      H Offline
                                      honey the codewitch
                                      wrote on last edited by
                                      #23

                                      Yeah I've coded in C and C++ for a long time, to the point where it doesn't confuse me. I just don't like the inconsistency. I understand why it is from a syntax perspective. In c#

                                      int[] array = new int[10];

                                      But in C it doesn't make sense to use new, and int[10] array; is ugly. Still, it just bugs me, because they're both type modifiers.

                                      Real programmers use butterflies

                                      1 Reply Last reply
                                      0
                                      • M Mike Winiberg

                                        Without wishing to start a major language debate, I think its important to understand that C was designed to be efficient at using the underlying hardware of the machine, and the way things are declared reflects this: char *sz declares a single variable that points to a place in memory, supposedly holding a char value. This pointer (and here's where dragons lie!) can be made to point to anywhere and to anything regardless of its declaration, you are just telling the compiler that at the place where that pointer points, YOU consider there to be a char value (whether it is or not in reality). char sz[1024] says that at the address represented by sz is a reserved block of memory that holds (in theory) 1024 char items. In your code you can (with some severe caveats!) use both variables in the same way and it's up to you to remember and manage whatever you think you are looking at in that location - this is both the beauty and danger of a language like C - it allows you to manipulate things in much the same way as in assembler and with as few restrictions, but it provides no protection against you doing something stupid. However, even the early compilers would detect if you attempted to treat these two variables as exactly equivalent, but would often only warn rather than prevent it, allowing you to create absolute havoc. Much code rot is caused by the developer incorrectly assuming that, by default, either of these variables is initialised (which is why most compilers these days will attempt to put something sensible in newly declared variables to protect the innocent). Before initialisation char *sz may contain a random address and even attempting to look at it might cause a total system crash if it accidentally points into hardware protected memory. With char sz[1024] though you can be sure that doing char x = *sz is safe because sz already holds a valid address and points into memory allocated to your program, what you don't know is what value you will actually get back from that place before the array is initialised. Why have I bored you all with this stuff? Because so many developers these days seem to know absolutely nothing at all about how the hardware they are driving works - that's fine if you are writing in a high-level domain specific language where everything like that is hidden - no help at all if you are writing a device driver for some complex piece of hardware that is integrated into an operating system of some sort.

                                        H Offline
                                        H Offline
                                        honey the codewitch
                                        wrote on last edited by
                                        #24

                                        I think you may have misunderstood me

                                        char[] sz = char[100];

                                        would be more consistent even if it requires extra typing. I'm not complaining about the way accessed either, just how it's declared. I don't mind that either way sz can be accessed via pointer or array index. In this case you could dereference it with a * like you can otherwise. I'm not arguing you shouldn't be able to. It's not a huge deal for me either. I've coded in the C and C++ for years so I'm used to it. It's just a syntax wrinkle i don't like.

                                        Real programmers use butterflies

                                        M 1 Reply Last reply
                                        0
                                        • H honey the codewitch

                                          Does it bother anyone else that you declare a pointer like:

                                          char* sz; // pointer type, pointer declared *with* type

                                          But an array is declared like this:

                                          char sz[1024];// array type, array declared *after* var name

                                          I think it's inconsistent, and I think the array specifier should have been declared with the type since it's essentially a type modifier like * and & Maybe it's just me?

                                          Real programmers use butterflies

                                          K Offline
                                          K Offline
                                          Kirk 10389821
                                          wrote on last edited by
                                          #25

                                          You are thinking about it the wrong way, I believe. There is an implicit Algebra: * = 1/& so, char *p, LITERALLY says (*p) is a char. therefore &(*p) => Address of that char! but knowing the algebra & and * cancel each other out (as do & and [) So, p is a pointer to a specific char. And the beauty of this, is that how you declare it usually implies how you are going to use it. A fixed array is declared as char a[10]; Which again, says (to me), I want an array of 10 characters, a POINTS to the first character, and a[1] == *(a+1). I always found this part of C very expressive and self-explanatory. Of course, I learned PDP/11 Macro-11 Assembly BEFORE I learned C. So most of this was mapping to register level access of R0 vs (R0) [Memory direct and indirect addressing]. Mov 65, R0 ; Stores the value in the register Mov 65, (R0) ; Stores 65 at the memory location of R0 Mov 65, (R0++) ; Stores 65 at the memory location and increments the memory location AFTER to the next ; Note its been 35 years, the syntax is illustrative of the features. If you know how the variable is declared, you should instantly understand the various ways you can dereference it.

                                          H 1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • World
                                          • Users
                                          • Groups