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

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

    It bothers me to no end. Actually what bothers me even more is that every time I mention it, I mostly get replies defending the stupid [Spiral of Death](http://c-faq.com/decl/spiral.anderson.html). It's bad enough that it's bad, but worse that people feel this kind of Stockholm Syndrome towards a type syntax that just doesn't make sense. (in some sense it's not even a type syntax, because it's not just a type, there's a declaration stuck in the middle of it) Anyway I'll show you something even worse, the syntax for returning a function pointer. Let's say you want to return a pointer to a function that takes two ints and returns an int, a function like `int add(int a, int b)` maybe. It would look like this:

    int (*getFunc())(int, int) { … }

    Unless you use a `typedef` of course (in C# that is essentially mandatory: you must declare a `delegate` with the signature first and then you can use that).

    H B 2 Replies Last reply
    0
    • L Lost User

      It bothers me to no end. Actually what bothers me even more is that every time I mention it, I mostly get replies defending the stupid [Spiral of Death](http://c-faq.com/decl/spiral.anderson.html). It's bad enough that it's bad, but worse that people feel this kind of Stockholm Syndrome towards a type syntax that just doesn't make sense. (in some sense it's not even a type syntax, because it's not just a type, there's a declaration stuck in the middle of it) Anyway I'll show you something even worse, the syntax for returning a function pointer. Let's say you want to return a pointer to a function that takes two ints and returns an int, a function like `int add(int a, int b)` maybe. It would look like this:

      int (*getFunc())(int, int) { … }

      Unless you use a `typedef` of course (in C# that is essentially mandatory: you must declare a `delegate` with the signature first and then you can use that).

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

      harold aptroot wrote:

      but worse that people feel this kind of Stockholm Syndrome towards a type syntax that just doesn't make sense

      I think you're the first person on this thread to agree with me. :laugh:

      Real programmers use butterflies

      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.

        J Offline
        J Offline
        James Lonero
        wrote on last edited by
        #50

        The latter may be the better notation since I can declare; int *pa, a; where pa is a pointer to an int and a is an int. If I declare int* pa, a; this is also legal, where pa is still a point to an int and a is an int.

        J 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

          J Offline
          J Offline
          Julie777
          wrote on last edited by
          #51

          It's hard to believe that of all the replies no one has ever read K&R C. A variable declaration consists of a type and name and possibly a type reference spec such as * or []. Multiple variable declarations may be combined in a single statement (line) if they are the same type. this is why reference specs go with the name

          char *sz, sz2[], sz3[1024];

          Types and reference specs can also have modifiers which are can get very confusing with multiple declarations combined on a line.

          static const char sz4, *sz5, const *sz6;

          Add initializers and you will see why it's pretty standard now days to put one declaration per line.

          B 1 Reply Last reply
          0
          • L Lost User

            It bothers me to no end. Actually what bothers me even more is that every time I mention it, I mostly get replies defending the stupid [Spiral of Death](http://c-faq.com/decl/spiral.anderson.html). It's bad enough that it's bad, but worse that people feel this kind of Stockholm Syndrome towards a type syntax that just doesn't make sense. (in some sense it's not even a type syntax, because it's not just a type, there's a declaration stuck in the middle of it) Anyway I'll show you something even worse, the syntax for returning a function pointer. Let's say you want to return a pointer to a function that takes two ints and returns an int, a function like `int add(int a, int b)` maybe. It would look like this:

            int (*getFunc())(int, int) { … }

            Unless you use a `typedef` of course (in C# that is essentially mandatory: you must declare a `delegate` with the signature first and then you can use that).

            B Offline
            B Offline
            BernardIE5317
            wrote on last edited by
            #52

            Greetings but I must differ int foobar(int, int) { return 0; } // I merely followed the operator rules of precedence and associativity for: // "f is a pointer to a function which takes two arguments of type int and int and returns an int" // and voila though the return type doesn't seem to be an operator unless perhaps a cast operator int (*f)(int, int) = foobar; // compiles ok int (*getFunc())(int, int) = foobar; // compiles with syntax error // Cheerios

            L 1 Reply Last reply
            0
            • J Julie777

              It's hard to believe that of all the replies no one has ever read K&R C. A variable declaration consists of a type and name and possibly a type reference spec such as * or []. Multiple variable declarations may be combined in a single statement (line) if they are the same type. this is why reference specs go with the name

              char *sz, sz2[], sz3[1024];

              Types and reference specs can also have modifiers which are can get very confusing with multiple declarations combined on a line.

              static const char sz4, *sz5, const *sz6;

              Add initializers and you will see why it's pretty standard now days to put one declaration per line.

              B Offline
              B Offline
              BernardIE5317
              wrote on last edited by
              #53

              Greetings and Kind Regards May I please direct you to my previous post. Cheerios The Lounge[^]

              1 Reply Last reply
              0
              • B BernardIE5317

                Greetings but I must differ int foobar(int, int) { return 0; } // I merely followed the operator rules of precedence and associativity for: // "f is a pointer to a function which takes two arguments of type int and int and returns an int" // and voila though the return type doesn't seem to be an operator unless perhaps a cast operator int (*f)(int, int) = foobar; // compiles ok int (*getFunc())(int, int) = foobar; // compiles with syntax error // Cheerios

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

                But that's not what I wrote. I wanted to *return* a function pointer from a function named `getFunc`.

                B 1 Reply Last reply
                0
                • L Lost User

                  But that's not what I wrote. I wanted to *return* a function pointer from a function named `getFunc`.

                  B Offline
                  B Offline
                  BernardIE5317
                  wrote on last edited by
                  #55

                  Greetings and Kind Regards Please permit me to demonstrate the following: By merely following the rules of operator precedence and associativity I deduce the same declaration for getFunc as yourself. I thank Harbison & Steele for teaching me this in their fine C text. Why K&R don't do this is difficult to understand. // "getFunc is a function which returns a pointer to a function which takes two int args and returns an int" // getFunc is a function ... getFunc() // ... which returns a pointer ... *getFunc() // ... to a function which takes two int args ... *getFunc()(int, int) (*getFunc())(int, int) // added ()'s because function call (int, int) has higher precedence than indirection * // ... and returns an int int (*getFunc())(int, int) // Voila No Spiral of Death is needed. Best Wishes Cheerios

                  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 codeproject
                    wrote on last edited by
                    #56

                    C declarations are fine. The problem is in C pointer expressions, where two unfortunate changes were made. First, Ritchie (I presume) chose to make * the pointer dereference operator and either chose or had forced upon him by the * choice the need to make it a *left* unary operator. Had he followed Wirth's prior example in Pascal (using p^ to dereference p), then your backwards issue is automatically solved. Why? Because C declarators are based on how the variable is used in an expression. So int *p; has the * first because you use *p in an expression to make use of the pointer. The array dimension come after the variable name: int a[5]; because you use a[index] in an expression to access a member of an array. If the pointer dereference was on the right, then you wouldn't need the quirky -> operator that only exists to cut down on parentheses, where p->member exists only to avoid typing (*p).member. By the way, the declaration should be "char *p;" instead of the awful "char* p;" that revisionists like to type. The * says that p is a pointer, not that "char" is a pointer. To see the difference, try using: int* p1, p2; /* this will NOT declare two integer pointers! */ The correct syntax is: int *p1, *p1; ...since the * says that what's on the right is a pointer. Again, this misunderstanding wouldn't even come up with a right-unary dereference operator. Most of the C language is admirable, particularly as a product of the early '70s, but this (along with allowing the and parts of libraries to become de facto standards) get my votes for Dennis Ritchie's biggest mistakes.

                    1 Reply Last reply
                    0
                    • J James Lonero

                      The latter may be the better notation since I can declare; int *pa, a; where pa is a pointer to an int and a is an int. If I declare int* pa, a; this is also legal, where pa is still a point to an int and a is an int.

                      J Offline
                      J Offline
                      Jeff Clausius SG
                      wrote on last edited by
                      #57

                      I was just to reply with the same. I always put the * modifier RIGHT in front of the variable. And it makes sense since, "char *" is not really the type. A lot of beginners are confused when something like the following: char* psz, pszHi, pszBye; and they discover pszHi / pszBye are just character variables. Code like the following helps those initiates: char *psz, *pszHi, *pszBye, chA, chB, *pszString3; Just my $0.02.

                      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