3 ms·
I was referring to this part of your original post: > It's also easy to make mistakes because of type mismatches. For example, if you pass `42` to a CGFloat pa
by btrask 10y ago
I was referring to this part of your original post:
> It's also easy to make mistakes because of type mismatches. For example, if you pass `42` to a CGFloat parameter, this works fine when you cast msgSend to the right type, but will fail amusingly if you rely on varargs to make it through.
All of your other claims are completely valid. This one, I'd say, is partially valid.
No need to pick nits with my usage of the word "prefers."
- mikeash 10y agoI don't understand what's debatable about that. Maybe an example would help? objc_msgSend(window, sel_registerName("setAlphaValue:"), 1); Versus: ((void (*)(id, SEL, CGFloat))objc_msgSend)(window, sel_registerName("setAlphaValue:"), 1); The former will set a garbage alpha value, the latter works. More generally, the former requires much more care and attention to get the types right, whereas the latter just requires that the cast match the method declaration.
- btrask 10y ago((void (*)(id, SEL, double))objc_msgSend)(window, sel_registerName("setAlphaValue:"), 1); If the method signature changes (unlikely for a system header, but possible if you're calling into your own code) then you're hosed. Or you could just mess up and copy/paste the wrong signature, or forget to change it. Basically, it's pretty error-prone no matter what you do. Using Objective-C directly is much safer (and luckily you usually can, since ObjC is pretty much a drop-in replacement for C).
- mikeash 10y agoI totally agree on all counts here. The cast saves you from this one specific thing but there's plenty more to go wrong. I think some people may overestimate the difficulty of adding some ObjC wrappers to a plain C project.