alliedmodders / sourcepawn

A small, statically typed scripting language.
Other
369 stars 63 forks source link

Unexpected array intailisation `char g_iArray[] = {0,1,2,3};` #490

Open c0rp3n opened 4 years ago

c0rp3n commented 4 years ago

When creating an array of chars with initailiser array of integer values it seems to create an array 4 * the expected size instead of converting the values to chars, not sure if this intended or not, but it is confusing, would expect these integers to be treated as chars in this case.

Test case:

#include <shell>

char g_iArray[] = {0,1,2,3};

public void main()
{
    print("Expected:\n");
    print("g_iArray[3] == 3\n");

    print("\nActual:\n");
    print("g_iArray[3] == %d\n", g_iArray[3]);
}

Output

Expected:
g_iArray[3] == 3

Actual:
g_iArray[3] == 0

I've reproduced this bug with the current release of the compiler in SourceMod build 6554.

c0rp3n commented 4 years ago

Asherkin stated this would be expected behavious and if so just makes the way to get the expected result rather long winded.

Current solution:

char g_cStr[] = "\x00\x01\x02\x03";

Also this does not compile

char g_cStr[] = { '\x00', '\x01', '\x02', '\x03' };

error 001: expected token: "}", but found "-integer value-"

dvander commented 4 years ago

The initializer parser is, without hyperbole, super duper extreme bad. I wouldn't consider this fixable without the upcoming array rewrite. So if that doesn't fix it outright, I'll make sure this gets fixed in a follow-up.

c0rp3n commented 3 years ago

Just an update on this the original case no longer compiles due to an array size mismatch.

Short example:

#include <shell>

char g_iArray[4] = {0,1,2,3};

public void main()
{
    for (int i = 0; i < 4; ++i)
    {
        printnum(g_iArray[i]);
    }
}
PS E:\programming\alliedmodders\sourcepawn\tests> ..\build\compiler\spcomp\windows-x86_64\spcomp.exe -i..\include\ -i.\ .\basic\char-array-int-assign.sp
SourcePawn Compiler 1.11
Copyright (c) 1997-2006 ITB CompuPhase
Copyright (c) 2004-2021 AlliedModders LLC

.\basic\char-array-int-assign.sp(3) : error 047: array sizes do not match, or destination array is too small

1 Error.

Using chars in the initialiser also does not work and produces the same error.

char g_iArray[4] = { '\x00', '\x01', '\x02', '\x03' };

Also removing the explicit size of the char array procuces the same error.

char g_iArray1[] = { 0, 1, 2, 3 };
// or
char g_iArray2[] = { '\x00', '\x01', '\x02', '\x03' };

So I guess currently it is an improvement as it does not compile and do something unexpected.

dvander commented 3 years ago

Your example with the hardcoded size looks like a compiler bug.