{"id":21768178,"url":"https://github.com/below/enumtest","last_synced_at":"2026-05-18T06:11:41.781Z","repository":{"id":66512579,"uuid":"53066466","full_name":"below/EnumTest","owner":"below","description":"A simple project to illustrate a possible Swift bug","archived":false,"fork":false,"pushed_at":"2020-11-23T14:49:32.000Z","size":17,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-07-30T20:37:53.790Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/below.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-03-03T16:42:44.000Z","updated_at":"2020-11-23T14:49:34.000Z","dependencies_parsed_at":"2023-03-13T20:29:44.562Z","dependency_job_id":null,"html_url":"https://github.com/below/EnumTest","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/below/EnumTest","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/below%2FEnumTest","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/below%2FEnumTest/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/below%2FEnumTest/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/below%2FEnumTest/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/below","download_url":"https://codeload.github.com/below/EnumTest/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/below%2FEnumTest/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":275457327,"owners_count":25468232,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-16T02:00:10.229Z","response_time":65,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-26T13:34:02.369Z","updated_at":"2025-09-16T17:17:34.720Z","avatar_url":"https://github.com/below.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Swift: The Dirty Secret of enum's rawValue\n\n## Abstract\n\nThe behavior of `init?(rawValue:)` for `enum` types imported from (Objective-)C is not well documented and can lead to confusion or errors in code\n\n## Update\n\nSwift 5.0 solves this issue with the `@unknown default` case\n\n## Introduction\n\nThe Swift language provides a lot of improvement over enums in (Objective-)C. They are _first-class types in their own right_, whereas in C they are basically just an `Int` container with a few fancy labels.\n\nThis leads to a problems which can easily be overlooked and are not obviously mentioned in the documentation. The documentation states that:\n\n_If you define an enumeration with a raw-value type, the enumeration automatically receives an initializer that takes a value of the raw value’s type and returns either an enumeration case or nil._ [(1)](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Enumerations.html)\n\n(Objective-)C Enums are automatically converted to Swift:\n\n_Swift imports any C enumeration marked with the NS_ENUM macro as a Swift enumeration with an Int raw value type._ [(2)](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithCAPIs.html)\n\nSo this:\n\n```C\ntypedef NS_ENUM(NSInteger, CEnum) {\n    Foo,\n    Bar\n};\n```\n\nbecomes this:\n\n```Swift\npublic enum CEnum : Int {\n    case Foo\n    case Bar\n}\n```\n\n## Does it really?\n\nAs stated above, a C enum can be assigned any integer value, without regard to a label being defined for that case. So `CEnum e = 4;` is perfectly valid.\nThus, a return value of type `CEnum` may contain any integer value. The only place where this is clearly documented is somewhere deep in the Swift source code on [github](https://github.com/apple/swift/blob/3ffbe020d76112c9a5f1bc05e64f272a9ba2ff6e/lib/ClangImporter/ImportDecl.cpp#L407):\n\n```Swift\n// Unlike a standard init(rawValue:) enum initializer, this does a reinterpret\n// cast in order to preserve unknown or future cases from C.\n```\n\n\nKnowning this, there are things to be aware of:\n\n## Issue One: No validity checking\n\nThis means, that for enums imported this way, `rawValue` will *not* return nil if no label can be found. This makes it impossible to check if a certain raw value corresponds to an existing label. Every possible raw value will return a valid object\n\n## Issue Two: Exhaustiveness\n\nSwift's `switch` statement demands to be exhaustive, that is you must cover every possible case, or insert a `default:` clause. The idea is to make sure that enumeration cases are not accidentally omitted. [(3)](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Enumerations.html) So what about our `CEnum`?\n\n```Swift\nif let e = CEnum(rawValue: 4) {\n    switch e {\n        case .Foo:\n            print (\"We have Foo\")\n        case .Bar:\n            print (\"We have Bar\")\n    }\n}\n```\n\nThe above is completely valid Swift code and will not lead to a compiler error. But what will happen at runtime? Even then, we are not informed of any issue and our `CEnum` with the value 4 is recognized as the first enumeration case, `.Foo`. One might think that `.Bar` would be the better choice, but it does not matter because neither is correct. \n\nWorse yet, the introduction of a `default:` case will generate the warning `warning: default will never be executed`. This is actually true: Even with the default case, our enum will be recognized as `.Foo`\n\nThat said, transforming the enum back into a raw value will correctly return the value `4` which provides a workaround to cover special cases with a `default:`case.\n\n## Summary \n\nAll the demonstrated issues of course arise from the behavior of enums in C, and Swift is simply trying it's best to emulate this behaviour.\n\nAs most, if not all, Apple Framework emums are currently imported from (Objective-)C, this concerns a significant number of enums that will be used in any given Swift app. Developers should be aware that sometimes what you see is not what you get. \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbelow%2Fenumtest","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbelow%2Fenumtest","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbelow%2Fenumtest/lists"}