4 ms·
> Everything we've seen here is still normal C, but often we want to associate a function with a type. For instance, the area function we have shown above only
by williamcotton 2y ago
> Everything we've seen here is still normal C, but often we want to associate a function with a type. For instance, the area function we have shown above only works with rectangles, but what if we had circles as well? We'd end up with two functions, one called area_rectangle and one called area_circle.
This is not to call the article into question but only to show that C11 does support generics, allowing for:
printf("Rectangle area: %.2f\n", area(rect));
printf("Circle area: %.2f\n", area(circle));
Full code here:
https://gist.github.com/williamcotton/a8f429e891cbba5abfadcc0a929dda00 https://gist.github.com/williamcotton/a8f429e891cbba5abfadcc...
- shakna 2y agoThough, bear in mind that _Generic is not generic templating. Highly useful, but it's more of a macro. You can run into issues with aliased types, or where types of the same size accidentally fall through into the wrong parts of the _Generic selector.
- npalli 2y agoYou haven't demonstrated the capability of Generics though (which C doesn't really have, only a minimal version). For this particular example, C++ does function overloading on parameters which C cannot hence you need this silly Generic macro hack, it is not clear how much of a win it is. Reminds of the saying that C is the most dynamic programming language since it has void* It is much cleaner in C++ where you don't need to declare two separate functions names like you did. #include <iostream> #include <cmath> struct Rectangle { double width; double height; }; struct Circle { double radius; }; double area(const Rectangle& rect) { return rect.width * rect.height; } double area(const Circle& circle) { return M_PI * circle.radius * circle.radius; } int main() { Rectangle rect{5.0, 3.0}; Circle circle{2.5}; std::cout << "Rectangle area: " << area(rect) << std::endl; std::cout << "Circle area: " << area(circle) << std::endl; return 0; }