Search code examples
clinuxwindowsvisual-studioclion

Why does this code bit work in clion but doesn't in VS


Hi I copied the following code from my linux machine with clion running. But in VS on Windows it seems to cause problems

entry_t* find_entry( char* n ) 
{
    // TODO (2)
    int x = strlen(n);
    char str[x];

    for (size_t i = 0; i < strlen(str); i++)
    {
        str[i] = toupper(n[i]);
    }

    n = &str;

    for (size_t i = 0; i < list_length; i++)
    {
        if (strcmp(n, name_list[i].name) == 0)
        {
            return &name_list[i];
        }
    }
}

VS underlines the x in char str[x]; before the statement do find x was in the brackets of str. I thought finding the length first in another variable would solve the problem

VS give the following error

Schweregrad Code Beschreibung Projekt Datei Zeile Unterdrückungszustand Fehler (aktiv) E0028 Der Ausdruck muss einen Konstantenwert aufweisen. Names.exe - x64-Debug C:\Users\Eyüp\source\repos\09\main.c 102

trying my best to translate it -> Error(active) E0028 Statement needs to be a constant value


Solution

  • Variable-length arrays (i.e. arrays whose size is not known at compile-time) are not supported in MSVC because they don't care. Hence you need to use malloc and friends instead.

    However that is not the only problem in your code: it has multiple undefined behaviours. Here is a suggested fix:

    entry_t* find_entry( char* n ) 
    {
        // return value of strlen is of type size_t, not int
        size_t x = strlen(n);
    
        // [x] was wrong, it needs to be [x + 1] for the null terminator!
        char *str = malloc(x + 1);
    
        // do not use strlen again in the loop. In worst case it does need 
        // to go through the entire string looking for the null terminator every time.
        // You must copy the null terminator, hence i <= x or i < x + 1
        for (size_t i = 0; i <= x; i++)
        {
            // the argument of toupper needs to be *unsigned char*
            str[i] = toupper((unsigned char)n[i]);
        }
    
        // why this did even exist? And it has type error anyway
        // n = &str;
    
        for (size_t i = 0; i < list_length; i++)
        {
            if (strcmp(str, name_list[i].name) == 0)
            {
                // need to free the str...
                free(str);
                return &name_list[i];
            }
        }
    
        // in both paths...
        free(str);
    
        // add default return value
        return NULL;
    }