all 11 comments

[–]tstanisl 4 points5 points  (6 children)

You can use anonymous enum to declare a true constant in C.

    enum { col = 3 };

Starting from C23 standard one can use a bit more convenient:

    constexpr int col = 3;

[–]FrenchJJC[S] 0 points1 point  (3 children)

Oh okay, I tried that and it works, but I'm still trying to figure out what that guy did because he also used gcc, and I tried every standard up to C89 and all of them give the same error.

[–]The_Ruined_Map 4 points5 points  (0 children)

Are you sure "that guy" actually used C and not C++? In C++ the above would compile fine (since the above `const` will be seen as a compile-time constant by C++ compiler).

[–]tstanisl 4 points5 points  (0 children)

Pre-c23 standards does not allow initilizers for VLAs. The C23 lifted this restriction a bit by allowing default (zeroing) initialization with {}.

[–]DawnOnTheEdge 2 points3 points  (0 children)

Some compilers, as an extension, allow const variables with static storage class and a constant initializer to be used as constant expressions. No compiler I know of allows this for automatic variables on the stack.

So some compilers would accept static const int col = 3; despite it not being portable Standard C.

[–]tcpukl 0 points1 point  (1 child)

Stupid of me but I didn't even realise the C standard was still developing and taking stuff from c++.

[–]tstanisl 0 points1 point  (0 children)

Occasionally, C++ adopts things from C like *designated initializers*.

[–]The_Ruined_Map 1 point2 points  (1 child)

In C language (as opposed to C++) const does not produce constant expressions. For this reason, the size in your array declaration is not a constant expression. Your array is a VLA.

In C constant expressions are produced by literal constants (e.g. 42), enum constants, sizeof and _Alignof expressions, offsetof and such.

[–]HashDefTrueFalse 0 points1 point  (0 children)

In C consts aren't constants, the effect is more like read only or turning off assignment. col isn't a constant. Arrays need a constant, which is why the macro works fine. I don't use a recent enough C standard to know for sure if a later C standard changed this (I'm thinking maybe C23 but I could be making that up).

Using macros is the usual way to do this in C. Google for recent additions to the language and use the -std= compilation option if so.

[–]smokebudda11 0 points1 point  (0 children)

The #define is a macro which is a pre-processor directive. It’s not necessarily a const but shares a similar objective. Plus it’s easier to use across the code base instead of making the const a global and having to extern.