Skip to content

[Feature Request] Handle if + cfg! in const context #1018

Open

Description

@GrayJack

Since the addition of if in const context, the usage of if + cfg! macro became a thing, since it reduces the need of replication of docs and definition.

pub const MYCONST: i32 = if cfg!(target_os = "linux") {
    10
} else if cfg!(windows) {
    5
} else {
    0
}

Currently, cbindgen ignores this kind of construction, but ideally, supporting that would make easier for maintaining C-exported constants that differ on targets.

Possible expected result:

#if defined(⟨USER_DEFINED_LINUX_FLAG_HERE⟩)
    #define MYCONST   10
#elsif defined(⟨USER_DEFINED_WINDOWS_FLAG_HERE⟩)
    #define MYCONST   5
#else
    0
#endif

In const context, an if must always have an else, so it is also common to have panicking macros, like panic!, unimplemented!, todo! and unreacheble! in the else clause. That causes an compiler error with the panic message if it reaches the panic. I think this could generate an #error directive with the message.

Example

pub const MYCONST: i32 = if cfg!(target_os = "linux") {
    10
} else if cfg!(windows) {
    5
} else {
    panic!("We only support linux and windows for now!")
}
#if defined(⟨USER_DEFINED_LINUX_FLAG_HERE⟩)
    #define MYCONST   10
#elsif defined(⟨USER_DEFINED_WINDOWS_FLAG_HERE⟩)
    #define MYCONST   5
#else
    #error "We only support linux and windows for now!"
#endif

Activity

  1. GrayJack commented on Oct 27, 2024

    @GrayJack
    ContributorAuthor

    Its unclear to me how this would work with the macro expansion feature. I'm not using the expasion feature in none of my projects that uses cbindgen

  2. GrayJack commented on Oct 27, 2024

    @GrayJack
    ContributorAuthor

    I currently have a working version for C/C++, but I have no idea how would be the equivalent for Cython to turn panics-> #error

  3. chrysn commented on Feb 3, 2025

    @chrysn

    Is there an established workaround for this?

    Right now I'm tempted to just place a manual copy of the cfg tree into the header, but then I'll also have to do the include guards manually.

  4. GrayJack commented on Feb 9, 2025

    @GrayJack
    ContributorAuthor

    Is there an established workaround for this?

    I think the only workaround for this is to create a bunch of #[cfg(...)] with the variable name for your const

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions