It's amazing and sad for computing that somehow managing to use a sane language to develop software for a very commonly used platform is seen as a serious feat of accomplishment.
C was not designed to create gui's. So its a feat of accomplishment as opening a bottle with your teeth.
OS X app in plain C
71–80 of 157 posts
Re: OS X app in plain C
#72Earlier quoted context omitted.
That seems slightly pedantic. While it's true that there's no cross-platform C ABI, most platforms have a C ABI, and it's well-defined (and defined in terms of C data types) on that platform. It's sort of like saying that there's no such thing as "rules of the road", because the road makers don't specify how you're supposed to drive on them, and the rules differ by jurisdiction and sometimes you're in a wilderness wi…
> That seems slightly pedantic. While it's true that there's no cross-platform C ABI, most platforms have a C ABI, and it's well-defined (and defined in terms of C data types) on that platform. Every platform has an ABI, obviously, and yes it's generally formed in view of C. This doesn't change the fact that the phrase "The C ABI" is, in a vacuum, meaningless and that "The C ABI on Platform X" is just a convoluted, c…
Put another way, I'm arguing that "C" is a more useful descriptor than "platform X's", because the sentence "Rust is compatible with the C ABI" is short for "forall X, Rust on platform X is compatible with the C ABI on platform X", and means something different from "Rust is compatible with the SysV ABI" (which implies that it follows the SysV ABI on Windows and OS X, too). And since the typical way of doing that is by interfacing with a C compiler or the C library (... and you could make this exact argument about the phrase "C library", I think), it's worth mentioning C. For instance, Vala and Nim, which both compile to C, are always compatible with the C ABI. If you port them to a mainframe they remain compatible with the C ABI, but not with the native ABI.
Re: OS X app in plain C
#73Earlier quoted context omitted.
I said you're right and I wasn't trying to disagree. I'm also a big fan of your blog and comments here (FWIW). As for whether casts add much safety, I admitted it's debatable. C++ prefers casts (e.g. on malloc) whereas C doesn't. A downside of using explicit casts is that if the type changes elsewhere in the program, the casts (spread throughout the code) can mask errors. If you write code such that casts are unneces…
I agree that unnecessary casts are undesirable, but that seems like a completely irrelevant point here, seeing as how the casts are not optional. C++ doesn't prefer casts, it requires them in places where C doesn't. Casting the return value from malloc isn't optional in C++ (unless you're assigning to a void *, anyway).
> 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."
Re: OS X app in plain C
#74Re: OS X app in plain C
#75Re: OS X app in plain C
#76Earlier quoted context omitted.
I agree that unnecessary casts are undesirable, but that seems like a completely irrelevant point here, seeing as how the casts are not optional. C++ doesn't prefer casts, it requires them in places where C doesn't. Casting the return value from malloc isn't optional in C++ (unless you're assigning to a void *, anyway).
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…
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.Re: OS X app in plain C
#77Don't do this at home. It looks so ugly because it's dangerous and vice-versa. If you really want to write (and read) code like this: id titleString = ((id ( )(id, SEL, const char ))objc_msgSend)((id)objc_getClass("NSString"), sel_registerName("stringWithUTF8String:"), "sup from C"); ((void (*)(id, SEL, id))objc_msgSend)(window, sel_registerName("setTitle:"), titleString); instead of this [window setTitle:@"sup"]; th…
Seriously, I don't know who's downvoting you. This needs a huge "for academic purposes only disclaimer". Higher level abstractions exist for a reason.
Re: OS X app in plain C
#78Earlier quoted context omitted.
> The ability to use a high-level, dynamic language (ObjC), C, and even inline assembly in a single source file is unique to Objective-C (at least among the "mainstream" languages), and something I think is often under-appreciated. You can even use C++, too, which is awesome. Putting Objective-C objects in C++ structs "just works" thanks to ARC. One thing most people don't know is that Objective-C was originally impl…
Objective-C was a modification of the GCC developed by NeXT. NeXT didn't publicly release their patches and the FSF/GNU threatened legal action. NeXT released their sources and the GCC now supports Obj-C. Source: https://en.wikipedia.org/wiki/GNU_General_Public_License#Leg...
No.
Objective-C was developed in the early '80s (as a C pre-processor, as the Grandparent post said) by Brad Cox, and commercialized by himself and Tom Love via a company they created together called Stepstone. Cox wrote a book about their product, Object Oriented Programming: An Evolutionary Approach, in 1986. I own a copy. It's pretty good!
Some time later, NeXT decided to build their user-space APIs around Objective-C, and bought the rights to Objective-C from Stepstone outright. It was at that point that they started modifying GCC to directly compile Objective-C rather than pre-process it into C.
Re: OS X app in plain C
#79Earlier quoted context omitted.
This is a very particular crowd, largely into web software and ecosystems for rapid growth of SaaS. I wouldn't extrapolate this crowd into software languages in general. You should always use the best tool for the job. Many people write quite excellent software in C/C++ every day. Just as many people use chainsaws, drive cars, fire guns and take pills every day. These are all productive activities with low floors and…
agree. If this was an enterprise/cio/it/gov discussion web site then all the conversations would be java and .net vs c++ if this was a scientific computing website then python, c/c++ and fortran and would be mentioned etc. if this was a hardware/firmware website it would be c vs (whatever black magic is used by hardware wizards).
Re: OS X app in plain C
#80Earlier quoted context omitted.
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…
I 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…
((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).