Skip to content

single_connected_component in wrapper.c might need minor modifications on windows using MSVC #37

@immorBen

Description

@immorBen

basic info:

  • branch: pymfinder-python3
  • os: windows server
  • MSVC

runing pyhton setup.py install raised below errors:

pymfinder/mfinder/wrapper.c(455): error C2057: expected constant expression 
pymfinder/mfinder/wrapper.c(455): error C2466: cannot allocate an array of constant size 0
pymfinder/mfinder/wrapper.c(455): error C2133: 'cc': unknown size
pymfinder/mfinder/wrapper.c(456): error C2057: expected constant expression                                                                                       
pymfinder/mfinder/wrapper.c(456): error C2466: cannot allocate an array of constant size 0                                                                        
pymfinder/mfinder/wrapper.c(456): error C2133: 'checked': unknown size                                                                                            
error: command 'C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\BIN\\x86_amd64\\cl.exe' failed with exit code 2   

chatgpt provided a solution that the below should be used (dynamically memory allocation):

int single_connected_component(int64 id, int mtf_sz) {
    int i, j, k;
    int added;
    
    Matrix *M;
    M = init_matrix(mtf_sz);
    fill_mat_id(M, id);

    // Allocate memory dynamically
    int *cc = (int *)malloc((mtf_sz + 1) * sizeof(int));
    int *checked = (int *)malloc((mtf_sz + 1) * sizeof(int));
    
    if (cc == NULL || checked == NULL) {
        fprintf(stderr, "Memory allocation failed\n");
        free(cc);
        free(checked);
        free_matrix(M);
        free(M);
        return FALSE;
    }
    
    for(i = 1; i <= mtf_sz; i++) {
        cc[i] = FALSE;
        checked[i] = FALSE;
    }

    cc[1] = TRUE;
    
    added = TRUE;
    while(added == TRUE) {
        added = FALSE;
        for(i = 1; i <= mtf_sz; i++) {
            if(cc[i] == TRUE && checked[i] == FALSE) {
                checked[i] = TRUE;
                for(j = 1; j <= mtf_sz; j++) {
                    if(MTRX(M, i, j) == 1 || MTRX(M, j, i) == 1) {
                        if(cc[j] == FALSE) {
                            cc[j] = TRUE;
                            added = TRUE;
                        }
                    }
                }
            }
        }
    }

    free(cc);
    free(checked);
    free_matrix(M);
    free(M);
    
    for(i = 1; i <= mtf_sz; ++i)
        if(cc[i] == FALSE)
            return FALSE;
    
    return TRUE;
}

it works for me (although still with some warnings, but...i'm a newbie, have no idea), test passed:

Ran 10 tests in 2.036s

OK

follow-up QAs:
Q: but this works without the above error on wsl, do different os treat the code of this function differently?
chatgpt:

Yes, different operating systems and compilers can treat code differently, especially when it comes to variable length arrays (VLAs). VLAs are part of the C99 standard and supported by GCC and Clang, but not by older versions of the Microsoft Visual C++ (MSVC) compiler.
In your case, the error occurs because MSVC does not support VLAs. On WSL (Windows Subsystem for Linux), GCC or Clang, which do support VLAs, are typically used, allowing the code to compile and run without issues.
To ensure compatibility across different compilers and platforms, it is best to avoid VLAs and use dynamic memory allocation instead, as demonstrated in the previous response. This approach makes your code more portable and ensures it works consistently on different systems and compilers.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions