When AI gets C++ bitmask enums almost right

When AI gets C++ bitmask enums almost right

Today I want to take a look at a piece of C++ code that Copilot generated for me recently. The code here will not be 1:1 the same because originally it was inserted as a part of the bigger code base - I changed the names and simplified it to focus on the key topic, but the overall idea is exactly the same. At first glance, the generated code looked perfectly reasonable. In fact, it even compiled. The problem is that it also contained a subtle semantic trap that is very easy to miss if you don't stop and think carefully about what the code is actually meant to do. The code started with an enum representing permissions where the values are bitmasks: enum class Permission { kNone = 0, kRead = 1 (static_cast(lhs) | static_cast(rhs)); } Enter fullscreen mode Exit fullscreen mode Nothing immediately suspicious here either, but the things start to look interesting because Copilot generated also a function that, according to some complex logic, returns combinations of permissions in form of: Permission GetPermissions() { return Permission::A | Permission::B; } Enter fullscreen mode Exit fullscreen mode This is where things start getting tricky. The code is not obviously wrong because representing flags as bitmasks is a completely valid technique, but let's test this with a simple example: Permission GetPermissions() { return Permission::kNone | Permission::kWrite; } int main() { const Permission p = GetPermissions(); std::cout (lhs) | static_cast(rhs); } Enter fullscreen mode Exit fullscreen mode Now the operator no longer falsely suggests that combining two permissions produces another valid enum field. Similarly, any function returning combined permissions should return an integer mask instead of Permission: int GetPermissions() { return Permission::kRead | Permission::kWrite; } int main() { const int p = GetPermissions(); std::cout (Permission::kRead)) { std::cout (Permission::kWrite)) { std::cout (Permission::kExecute)) { std::cout << "Execute"; } std::cout << std::endl; } Enter fullscreen mode Exit fullscreen mode Now the output becomes: Current permissions: ReadWrite Enter fullscreen mode Exit fullscreen mode

Original Source

Read the full article at Dev →

KhanList aggregates and links to publicly available news content. We do not host full articles from third-party sources. Always verify important information with original sources.