-3

I was writing some code in C and I wrote: static const unsigned char foo[]. Which made me wonder, what is the greatest number of unique keywords (and what are those keywords) that I can add in front of a variable in valid c11?

Axel Munoz
  • 77
  • 3
  • `static _Thread_local const volatile _Atomic unsigned long long int` –  Jul 22 '20 at 12:22
  • see [cppreference on declarations](https://en.cppreference.com/w/c/language/declarations) – Hulk Jul 22 '20 at 12:23
  • 1
    @StaceyGirl Make it a pointer and you could add another `const` that is semantically different from the first. :) – Some programmer dude Jul 22 '20 at 12:33
  • 1
    @Someprogrammerdude ...as well as `volatile` and `_Atomic`. And this can be continued indefinitely. –  Jul 22 '20 at 12:34
  • 1
    I’m voting to close this question because Stack Overflow is limited to **practical**, answerable questions, with answers that allow you to solve a *specific problem* encountered in the process of software development. Questions that are games or only for the sake of curiosity are off-topic here. – Charles Duffy Jul 22 '20 at 19:27
  • 2
    (Back in the early days of Stack Overflow such questions were welcome here, but we kicked all the games/quizzes/just-for-fun things out to our sister site [codegolf.se]. There's related discussion on [meta], in the accepted answer to [What is the rationale for closing "why" questions on language design?](https://meta.stackexchange.com/questions/170394)). – Charles Duffy Jul 22 '20 at 19:29

3 Answers3

2

No limits, since you can add any number of const* to create a different type:

int const* const* /* ... */ const* const* i = 0;

Godbolt

Aykhan Hagverdili
  • 28,141
  • 6
  • 41
  • 93
  • Oh that's very interesting, I did not know that! While you are 100% correct, I guess I was looking for unique keywords :) I'll update that question, but good answer! – Axel Munoz Jul 22 '20 at 12:29
  • 1
    @AxelMunoz: `unsigned long long` is different from `unsigned long`; you can't simply say "no repetition". – Jonathan Leffler Jul 22 '20 at 13:44
  • That's a very good point! I'm not sure how to quite phrase the sentiment where the repetition of `const` is "cheating", but `long long` is okay. I guess no repetition of keywords that have no additional effect. – Axel Munoz Jul 22 '20 at 13:51
  • @AxelMunoz how about now? Each `const*` creates a different pointer type, has an "additional effect" – Aykhan Hagverdili Jul 22 '20 at 13:53
  • *you can add any number of `const*`* [The C11 standard](https://port70.net/~nsz/c/c11/n1570.html#5.2.4.1) only says "at least 12". – Andrew Henle Jul 22 '20 at 19:32
  • @AndrewHenle that's of course an implementation limitation, and this one is a theoretical question. – Aykhan Hagverdili Jul 22 '20 at 20:19
  • You don't even need pointers for this. `int const const const i = 0;` etc is valid too. Declarations isn't the most rational part of the C language... – Lundin Jul 27 '20 at 14:38
  • @Lundin This answer originally had your version (see the [1st revision](https://stackoverflow.com/revisions/63034189/1)). OP then [pointed out](https://stackoverflow.com/questions/63034068/what-is-the-greatest-number-of-unique-keywords-you-can-add-to-a-variable-in-c/63034189?noredirect=1#comment111470230_63034189) that they want each keyword to "have an effect", so I added the pointers. – Aykhan Hagverdili Jul 27 '20 at 14:58
2

That's what I tried what works (Proof):

_Thread_local static const volatile _Atomic unsigned long long int a - 9 unique keywords for a usual data variable.

_Thread_local static const volatile _Atomic unsigned long long int * restrict const volatile b; - 12 for a single level pointer variable. Note that the keywords which are equal belong to either the object the pointer point to or the pointer itself (except long long which isn't a repetition as rather a type definition).

Since you technically can use an unlimited amount of pointer levels, the amount of keywords should raise exponential to this.

0

Here are the rules as taken from the C 2011 Online Draft:

  1. Zero or one of the following storage class specifiers:
    • auto
    • extern
    • register
    • static
    • typedef

    The _Thread_local storage class specifier may appear on its own or with the static or extern storage class specifiers;
  2. Zero or more of the following type qualifiers, depending on what you're qualifying:
    • const
    • volatile
    • restrict - only valid for pointers to object types
    • _Atomic - not valid for array or function types
  3. One of the following combinations of type specifiers:
    • void
    • char, signed char, or unsigned char
    • short, short int, signed short, signed short int, unsigned short, or unsigned short int
    • int, signed, signed int, unsigned, or unsigned int
    • long, long int, signed long, signed long int, unsigned long, or unsigned long int
    • long long, long long int, signed long long, signed long long int, unsigned long long, or unsigned long long int
    • float
    • double or long double
    • _Bool
    • float _Complex, double _Complex, or long double _Complex
    • Atomic type specifier
    • struct or union specifier
    • enum specifier
    • typedef name
  4. Zero or more of the following function specifiers - for function types only:
    • inline
    • _Noreturn
  5. Zero or one alignment specifier _Alignas - not valid for bitfields, functions, or anything declared with the register storage class or a typedef name

So, you could have atrocities like

static _Thread_local const volatile _Atomic _Alignas (void *) unsigned long int * restrict ptr;

or

extern _Thread_local const volatile inline _Noreturn unsigned long int foo(void);
John Bode
  • 119,563
  • 19
  • 122
  • 198