Const breakage on arrays
const keyword produces unexpected behavior for arrays
#include <sourcemod>
enum struct Test {
int x;
float y;
char z[32];
}
/* warning 213: tag mismatch
* error 008: must be a constant expression; assumed zero */
const Test g_test = {1, 2.0, "Hello"};
/* error 001: expected token: "=", but found "[" */
const int g_ints[] = {1, 2, 3, 4};
public void OnPluginStart() {
/* error 001: expected token: "=", but found "["
* error 029: invalid expression, assumed zero */
const int ints[] = {5, 6, 7, 8};
/* error 001: expected token: "=", but found "["
* error 029: invalid expression, assumed zero */
const char str[] = "Hi";
PrintToServer("%i %f %s %i %i %i %s",
/* error 104: cannot find any methods for Test */
g_test.x, g_test.y, g_test.z, g_ints[3], ints[0], ints[3], str
); // 1 2.0 Hello 4 5 8 Hi
}
The const keyword is only valid on by-ref parameters currently. Obviously those error messages aren’t the best though.
~~What is this then? https://github.com/alliedmodders/sourcepawn/blob/b9f7786cfcaebf4a3f2a986f09da18628ad03fba/tests/basic/const-decl.sp~~
The above code seems to have been valid in 1.10. I didnt remember global non-array consts being a thing. Can I make this a feature request then?
It seems arrays can still be made constant if placing the keyword static in front of them.
#include <sourcemod>
enum struct Test {
int x;
}
static const Test g_test = {1};
static const int g_ints[] = {1, 2, 3, 4};
public void OnPluginStart() {
PrintToServer("%i %i", g_ints[0], g_test.x);
g_ints[1] = 2; // must be lvalue (good). compiles if commented
g_test.x = 2; // No error (bad)
}
Nope, it was never valid. The reason "static" works is because of a quirk in the parser. A "const" symbol does not allocate storage space, so it doesn't go through the variable parsing code. Since the intent is compile-time constants only, it is not capable of parsing arrays.
However, "static" implies storage space, so it always goes through variable parsing, which allows "const".
Is this the ideal behavior? Probably not. I've been meaning to unify these, and elide the variable declaration as an optimization (if the right-hand-side is a compile-time evaluated expression). I'll keep the issue open as a feature request.