discuss-gnustep
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Which ObjC2.0 features are missing in the latest GCC?


From: David Chisnall
Subject: Re: Which ObjC2.0 features are missing in the latest GCC?
Date: Thu, 21 Nov 2019 08:32:18 +0000

> On 20 Nov 2019, at 20:11, Gregory Casamento <address@hidden> wrote:
> 
> Derek
> 
> On Wed, Nov 20, 2019 at 1:44 PM Derek Fawcus <address@hidden> wrote:
>> On Wed, Nov 20, 2019 at 10:52:36AM +0000, David Chisnall wrote:
>> > Oh, and with ARC, all of the C++ implementations have correct memory 
>> > management for Objective-C, for free.
>> 
>> While dropping support for GCC does not strike me as a problem,
>> switching the core implementation to depend upon C++ may well do.
> 
> I'm not sure what to say to this other than LOL.  Given that C++ still 
> doesn't have some of the dynamic features of even the original ObjC it seems 
> quite impossible.  Also it contradicts the entire purpose of the framework... 
>   moving on…

I think you are missing my point here.  C++ is a good language for low-level 
abstractions, for abstract data types, and so on, with aggressive compile-time 
specialisation and opportunities for optimisation at the low level.  In 
contrast, Objective-C is a good language for providing stable interfaces, for 
high levels of abstraction, and so on.

Apple and WinObjC both use C++ internally to implement a lot of the Objective-C 
classes.  Objective-C++ lets you use C++ features in the implementation and 
export Objective-C interfaces.  This gets you the best of both worlds.  A few 
years ago, I experimented with creating an NSMutableDictionary concrete 
subclass that used std::unordered_map in the implementation.  It was less code 
than the GSIMap-based version in GNUstep, with ARC all of the memory management 
was free, and it performed better.  I used a typedef for the concrete type that 
it used for the C++ map object and so I could switch between one of a dozen 
open source hash table implementations by changing two lines of code (the 
#include line for the map and the typedef line for picking which type to use).  
Try doing that in Objective-C...

In my own code, if I use Objective-C frameworks, I now use Objective-C++ 
exclusively.  NSDictionary lets my have a map from objects to objects, but what 
if I want a map from objects to selectors or integers to objects?  I can only 
do this with NSDictionary if I box the non-object version.  In contrast, I can 
write:

std::unordered_map<id, SEL> foo;
std::unordered_map<int, SomeObjCClass*> foo;

And both of these Just Work™.  I can also do things like:

std::unordered_map<int, __weak id> foo;

And get a map from integers to weak objects.  If I decide that this isn’t 
sufficiently efficient, I can replace it with something like llvm::DenseMap or 
tsl::robin_map with a trivial code change - but I can defer that optimisation 
until I’ve done some profiling and determined that it actually matters.

From the perspective of C++, Objective-C object pointers are objects that have 
a non-trivial copy constructor and destructor.  Anything that correctly handles 
C++ ownership correctly handles Objective-C memory management.  

Outside of the framework that I’m implementing, I can still expose Objective-C 
interfaces and benefit from all of the loose coupling that dynamic dispatch and 
non-fragile instance variables imply.

>>> How many developers are comfortable with C++?
>> 
>> I am comfortable with it, but not for the purposes of GNUstep.
>> I gave up on it a number of years ago, simply because IMO it was
>> too complex and fragile; basically I viewed it as an engineering
>> nightmare.
> 
> Gave up on what?  GCC or C++?

Most people that have this opinion about C++ have not looked at it since C++11 
became mainstream.  C++98 was a terrible language.  C++11 filed off most of the 
rough corners.  C++14 and C++17 both improved things and C++17 is now a nice 
language.

To give another data point, we have recently open sourced a memory allocator 
written in C++[1].  I am doing most of my development work in a FreeBSD VM that 
has replaced jemalloc in libc with it.  jemalloc is a usually the go-to 
allocator for when people want higher performance (FireFox uses it, for 
example, and it’s the default allocator on Android).  jemalloc is written in C. 
 The binary for snmalloc is about half the size, it performs better, and we 
have done several aggressive refactorings that improve performance (our 
allocation fast path - hit most of the time for allocations under 64KiB - is 15 
x86-64 instructions, our fast path for deallocation is 25). There’s nothing in 
snmalloc that we couldn’t have written in C, but we have a number of tables 
that are generated from a mixture of constexpr and templates that are easy to 
modify in our codebase and which are generated in Python scripts in other 
allocators that do similar things.

>  
>> Every project I've seen using it (either public, or commercial)
>> seem to use a different subset, and it can be difficult to spot
>> when a mechanism outwith that subset accidentally creeps in.
>> 
> ??? 

Again, this was completely true until around 2012, since then most C++17 
projects have more or less converged.  There are static analysis checkers for 
different sets of guidelines and the only real distinction is whether you want 
to permit RTTI and exceptions or not.  These are compile-time flags and code 
that violates the rules will fail to compile.

David

[1] https://github.com/microsoft/snmalloc


reply via email to

[Prev in Thread] Current Thread [Next in Thread]