[lkml]   [2006]   [Apr]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
    SubjectRe: C++ pushback
    Denis Vlasenko wrote:
    > On Thursday 27 April 2006 11:07, Avi Kivity wrote:
    >> C++ compilation isn't slower because the compiler has to recognize more
    >> keywords. It's slower because it is doing more for you: checking types
    >> (C++ code is usually free of void *'s except for raw data) and expanding
    > Today's C is much better at typechecking than ancient K&R C.

    It still can't typecheck void pointers. With C++ they're very rare.

    Look at the contortions needed to get the min() macro to be typesafe.

    >> those 4-line function to their 14-line goto-heavy equivalents.
    > Where do you see goto-heavy code in kernel?

    [avi@cleopatra linux]$ grep -rw goto . | wc -l

    Repeat without 'wc' to get a detailed listing.

    >> C++ works excellently for things like list_head. The generated code is
    >> as efficient or better that the C equivalent,
    > "or better" part is pure BS, because there is no magic C++ compiler
    > can possibly do which is not implementable in C.

    For list_head, no. But coding more complex data structures as type-safe
    macros is not practicable.

    As an example, you can easily get C++ to inline the hash function in a
    generic hashtable or the compare in a sort. I dare you to do it in C.

    > "as efficient", hmmm, let me see... gcc 3.4.3, presumably an contemporary
    > C++ compiler, i.e. which is "rather good".

    4.1.0 is the latest.

    > Random example. gcc-3.4.3/include/g++-v3/bitset:

    You're looking at a library while we were talking about the language and
    compiler. But anyway.

    > template<size_t _Nw>
    > struct _Base_bitset
    > {
    > typedef unsigned long _WordT;
    > /// 0 is the least significant word.
    > _WordT _M_w[_Nw];
    > _Base_bitset() { _M_do_reset(); }
    > ...
    > void
    > _M_do_set()
    > {
    > for (size_t __i = 0; __i < _Nw; __i++)
    > _M_w[__i] = ~static_cast<_WordT>(0);
    > }
    > void
    > _M_do_reset() { memset(_M_w, 0, _Nw * sizeof(_WordT)); }
    > ...
    > A global or static variable of _Base_bitset or derived type
    > would need an init function?! Why not just preset sequence of
    > zeroes in data section?

    I wouldn't count startup time as efficiency, unless you have several
    million global bitset objects.

    > [this disproves that C++ is very efficient]

    Add a constructor which does not touch the data members, and the data
    will (probably) end up in .bss.

    > Why _M_do_set() doesn't use memset()?

    Patches accepted :)

    It's just a library, you're free to optimize it. I'd guess that
    _M_do_set() is very rarely called, and that the performance difference
    is small anyway.

    > Why _M_do_reset() is not inlined?

    It is inlined. Why do you think it is not?

    > [this disproves that today's C++ libs are well-written]?

    Certainly, one can't claim that all C++ libraries are will written. But
    gcc library mostly is.

    Again, if you don't like some library, don't use it. The kernel would
    use its own version anyway since it has to be freestanding.

    >> and the API is *much*
    >> cleaner. You can iterate over a list without knowing the name of the
    >> field which contains your list_head (and possibly getting it wrong if
    >> there is more than one).
    > But kernel folks tend to *want to know* everything, including
    > names of the fields.

    The names of the fields are not hidden. You just don't have to
    mindlessly repeat them.

    The 'know everything' argument seems to apply equally well to ordinary
    functions: "I *must know* about calls to schedule() and those expensive
    atomic operations, don't hide them behind mutex_lock()!"

    >>> How could that possibly work in C++ given what you've said? Anything
    >>> that breaks code that simple is an automatic nonstarter for the
    >>> kernel. Also remember that spinlocks are defined preinitialized at
    >>> the very earliest stages of init. Of course I probably don't have to
    >>> say that anything that tries to run a function to iterate over all
    >>> statically-allocated spinlocks during init would be rejected out of hand.
    >> Why would it be rejected?
    >> A static constructor is just like a module init function. Why are
    >> modules not rejected out of hand?
    > Because we do not like init functions which can be eliminated.
    > That's bloat.

    I'm sure you can eliminate them if you want, but working to remove some
    microseconds of boot time is a complete waste of effort IMO.

    error compiling committee.c: too many arguments to function

    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to
    More majordomo info at
    Please read the FAQ at

     \ /
      Last update: 2006-04-27 16:30    [W:0.029 / U:5.148 seconds]
    ©2003-2017 Jasper Spaans. hosted at Digital OceanAdvertise on this site