Live data from Hacker News

Some Obscure C Features

multun.net

11–20 of 147 posts

Re: Some Obscure C Features

#11
post #9

Here is an obscure c feature: int main() { int a = 8; { int a = 4; /* a is only scoped to this block */ } printf("%d", a); /* prints 8 */ } It is also why C++ is not a strict superset of C

> It is also why C++ is not a strict superset of C

Can you explain? That code in C++ also scopes ‘a’ to the block.

EDIT: I see you’ve edited the code, but I think it’s still true in C++. I’ve often done that for RAII and unless I’m mistaken it works just as well when shadowing variables like you’re doing as when not.

Re: Some Obscure C Features

#13
The preprocessor trick of passing function macros as parameters is not that obscure. I have seen it used and I've used it myself. It is very useful when you have a list of static "things" that you need to operate on.

Say I have a static list of names and I would like to declare some struct type for each name. I also would like to create variables of these structs at some point, and I would always do so for the entire block of names. You could do something like this:

    #define apply(fn) \
        fn(name1) \
        fn(name2) \
        fn(name3) \
        ...
        fn(nameN)

    #define make_struct(name) struct name##_t { ... }
    #define make_variable_of(name) name##_t name;
    
    ...

    apply(make_struct);  // This defines all the structs.
 
    void some_function(...) {
        apply(make_variable_of);  // And this defines one variable of each type.
    }
Yes, it is not pretty (it is the C preprocessor after all), but it can be very useful and clean.

Re: Some Obscure C Features

#14
post #7

Although calling the preprocessor "functional" is being too pleasant. The C preprocessor was always a text substitution system, so macro as parameter is not that "obscure". Of course, I may have missed something subtle in the example. It's also not clear how to use that preprocessor example.

It can be very useful! I added a small comment with an example of how I used it once.

Re: Some Obscure C Features

#15
post #13

The preprocessor trick of passing function macros as parameters is not that obscure. I have seen it used and I've used it myself. It is very useful when you have a list of static "things" that you need to operate on. Say I have a static list of names and I would like to declare some struct type for each name. I also would like to create variables of these structs at some point, and I would always do so for the entire…

I'd say none of the preprocessor stuff on this list is obscure--I've seen all of them in projects before.

Re: Some Obscure C Features

#16
post #9

Here is an obscure c feature: int main() { int a = 8; { int a = 4; /* a is only scoped to this block */ } printf("%d", a); /* prints 8 */ } It is also why C++ is not a strict superset of C

That's hardly obscure: it's Javascript that's the odd one out of the languages with C-like syntax, with its wacky function-level scoping instead of variable shadowing when using 'var', and falling back to global scope when not declaring a variable properly. Also, C and C++ behave identically with your given example.

A perhaps obscure feature is that you can "unshadow" a global variable like this:

  #include 
  int global = 0;
  int main()
  {
    int global = 1;
    {
      extern int global;
      printf("%d\n", global); // prints 0
    }
  }

Re: Some Obscure C Features

#17
post #9

Here is an obscure c feature: int main() { int a = 8; { int a = 4; /* a is only scoped to this block */ } printf("%d", a); /* prints 8 */ } It is also why C++ is not a strict superset of C

I don't think that's obscure at all. That's standard lexical scoping. Do it all the time in functional languages.

Re: Some Obscure C Features

#18
post #9

Here is an obscure c feature: int main() { int a = 8; { int a = 4; /* a is only scoped to this block */ } printf("%d", a); /* prints 8 */ } It is also why C++ is not a strict superset of C

Off the top of my head, I can't think of any language that doesn't permit this. See https://en.wikipedia.org/wiki/Variable_shadowing

Re: Some Obscure C Features

#19
post #9

Here is an obscure c feature: int main() { int a = 8; { int a = 4; /* a is only scoped to this block */ } printf("%d", a); /* prints 8 */ } It is also why C++ is not a strict superset of C

If you want to tell if your compiler is C or C++, run this program:

   #include 
   int main() {
     printf("%d\n", sizeof('a'));
   }
It's the second thing C++ mentions in its list of incompatibility with C (the first is "new keywords").

A more obscure difference is this program:

   int i;
   int i;
   int main() {
     return i;
   }
It's legal C but not legal C++.
Post reply on HN