Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

errno constants not usable in switch-case #134

Closed
ahgamut opened this issue Mar 24, 2021 · 2 comments
Closed

errno constants not usable in switch-case #134

ahgamut opened this issue Mar 24, 2021 · 2 comments
Labels
wontfix This will not be worked on

Comments

@ahgamut
Copy link
Collaborator

ahgamut commented Mar 24, 2021

When using a switch statement, constants that are part of errno.h (ENOENT, EACCES etc.) are not available as case labels at compile-time.

Minimal example:

#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>

int main(void) {
    int res = 0;
    errno = 0;
    res = open("./nonexist.txt", O_RDONLY);
    printf("res = %d, errno == ENOENT? %s\n", res, (errno == ENOENT ? "yes" : "no")); // this is OK
    switch (errno) {
        case ENOENT: // this causes a compilation error
            printf("custom message: file doesn't exist!\n");
            // do something
            break;
        default:
            printf("\n");
    }
    return 0;
}

The following compilation error is raised when attempting to compile with cosmopolitan libc.

hello.c: In function ‘main’:
hello.c:12:9: error: case label does not reduce to an integer constant
         case ENOENT:
         ^~~~
@jart
Copy link
Owner

jart commented Mar 24, 2021

Code that uses switch on system constants needs to be updated to use if statements. That's unavoidable unfortunately. It's the one major breakage we needed to make in terms of compatibility. The tradeoff is explained in the APE blog post:

That one thing aside, if it's this easy, why has no one done this before? The best answer I can tell is it requires an minor ABI change, where C preprocessor macros relating to system interfaces need to be symbolic. This is barely an issue, except in cases like switch(errno){case EINVAL:...}. If we feel comfortable bending the rules, then the GNU Linker can easily be configured to generate at linktime all the PE/Darwin data structures we need, without any special toolchains. https://justine.lol/ape.html

@ahgamut
Copy link
Collaborator Author

ahgamut commented Jun 8, 2023

@jart seems like we can avoid most of it after all 🙂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
wontfix This will not be worked on
Projects
None yet
Development

No branches or pull requests

2 participants