|
|
Subscribe / Log in / New account

C, still?

C, still?

Posted Sep 20, 2017 16:43 UTC (Wed) by ncm (guest, #165)
In reply to: C, still? by eru
Parent article: Building the kernel with Clang

> It seems to me a kernel is the one place where you don't want
> the compiler doing things behind your back. You need to stay
> in control. The things C++ adds to C are all about hidden magic.

There was a time you could say this, and the greybeards would nod silently and go back to scraping barnacles. But they're dead now, and the greybeards we have today know better.

We know that you aren't obliged to hide what is better not hidden. We know the magic isn't about hiding essential details, it's about whole categories of mistakes made impossible, and the attention spared from watching out for those available for better things. In all programming, no less in kernel programming, by far the scarcest commodity is attention. More productively-applied attention means better code: faster (yes, good C++ code is routinely faster), and doing more of the right things, and fewer of the wrong things. Compilation may be slower (although not compilation of the C subset -- guess what, Gcc uses the same code for both!), but with fewer trivial mistakes that have big consequences, you come out far ahead.

Nobody seriously suggests rewriting Linux in C++, just as nobody suggests rewriting Gcc (although somebody wrote Clang). But an increasing fraction of Gcc is good C++, and is visibly better for it. (Who hasn't noticed Gcc getting better, faster? It's not just competition from Clang.) Linux is coded in C, but C is bad C++, and new code could be good C++.

A totally new kernel in a modern language might be better than a mixed C and C++ Linux, but Linux is what we can have, and Linux can be made better than what we do have, with overwhelmingly less work. Over time, it will be noticed that the overwhelming majority of the bugs, by proportion, are in the old C code, and the quality standard will rise.


to post comments

C, still?

Posted Sep 21, 2017 9:19 UTC (Thu) by NAR (subscriber, #1313) [Link] (8 responses)

"Compilation may be slower (although not compilation of the C subset -- guess what, Gcc uses the same code for both!)"

If you're only using the C subset of C++ then why are you compiling with the C++ compiler in the first place? The slowness starts with C++-specific stuff, each usage of e.g. std::map<std::string, std::string> includes so much code eventually that it really slows down compilation. Once I read a story about a C++ project that took 2 hours to compile. One developer was bored and copied all code of the project into a single source file: it was compiled in 7 minutes. This is the problem that the C++ ecosystem needs to solve.

C, still?

Posted Sep 21, 2017 11:09 UTC (Thu) by mathstuf (subscriber, #69389) [Link]

There are proposals for modules in the standards committee. The problem with it that I see is that it will require massive overhauls to all of the build tools for proper support. Unless you can determine the module output just from the filename or a basic scan of a file's contents, you need to compile it to see what modules a file will create or consume, so you need a pass before everything else that determines this before you start your real compilation. For example, ninja currently has no support for this (see Brad King's PRs for Fortan support; it's the same logic necessary).

C, still?

Posted Oct 1, 2017 0:42 UTC (Sun) by philomelus (guest, #96366) [Link] (6 responses)

There are ways to fix this that are easy and straight forward. The fact that none of the common c/c++ libraries implement them is a shame.

For an example:

Have you seen something like this in a header?

#ifndef __FOO_H__
#define __FOO_H__
...
#endif // __FOO_H_

That in itself isn't enough. The point of the macro is to prevent reloading a file. If the entire file has to be read in order to exclude it (e.g. compiler has to find the matched #endif because it could be a #else or something), you've gained very little. What saves compilation time is NOT reading the files to begin with.

My projects have used the following structure for more than 20 years (yes, since cfront days):

In source, or header if you like:

#ifndef __FOO_H__
#include "foo.h"
#endif

Then in header, at line 1:

#ifndef __FOO_H__
#define __FOO_H__
// Header comments, (c) notice, license notice, etc.

// other stuff as usual
#endif

Doing the above makes the top of the source files a bit "ugly" in some folks opinion, but the compile time savings are well worth it. With modern c++ template meta programming, one can even make this happen without much involvement of the end user (the programmer, that is).

C, still?

Posted Oct 1, 2017 2:43 UTC (Sun) by viro (subscriber, #7872) [Link] (1 responses)

Compiler can trivially recognize that file is guarded that way (i.e. that having a macro defined guarantees that everything inside will be ifdef'ed out) and skip running a tokenizer over that thing. I've never checked in gcc and clang do that, but sparse sure as hell does and implementation is nothing tricky. See already_tokenized() and handle_ifndef() in pre-process.c; it's really not hard to do. Comments in commit eac4d539b83e ([PATCH] fixed stream->protect handling) describe the logics of the current implementation. If any compiler out there doesn't handle that without rereading/retokenizing the files - just fix it...

C, still?

Posted Oct 17, 2017 21:39 UTC (Tue) by nix (subscriber, #2304) [Link]

Compiler can trivially recognize that file is guarded that way (i.e. that having a macro defined guarantees that everything inside will be ifdef'ed out) and skip running a tokenizer over that thing. I've never checked in gcc and clang do that
GCC certainly does. See the first few conditionals in libcpp/files.c:should_stack_file(). This is even documented (in the node 'Once-Only Headers' in the cpp info doc).

C, still?

Posted Oct 1, 2017 7:17 UTC (Sun) by NAR (subscriber, #1313) [Link]

The problem is that for every single compilation unit that uses std::map<std::string, std::string> the compiler actually has to read the relevant headers. If there are 20 C++ sources files in the directory using the std::map<std::string, std::string> type, the headers will be read and compiled 20 times. ifdef's don't help at all. What would help is using a single file instead of 20 files but that has other problems.

C, still?

Posted Oct 1, 2017 18:24 UTC (Sun) by madscientist (subscriber, #16861) [Link] (1 responses)

Every compiler I've used in the last 5 years supports the "#pragma once" facility. This is much cleaner than ifdefs and just as fast as the "ifdefs around the #include" method you are suggesting.

It isn't standard of course, so if you require maximum portability you can't use it.

C, still?

Posted Oct 5, 2017 9:25 UTC (Thu) by mathstuf (subscriber, #69389) [Link]

Doesn't that have issues with copies of the header floating around though? Though I guess you have "which was first?" questions anyways in similar situations using guards, so maybe it isn't so bad.

include guard

Posted Oct 1, 2017 19:44 UTC (Sun) by Jandar (subscriber, #85683) [Link]

For more than a decade gcc recognizes an include guard and doesn't open the file a second time.

https://gcc.gnu.org/onlinedocs/cppinternals/Guard-Macros....

C, still?

Posted Sep 21, 2017 15:19 UTC (Thu) by nix (subscriber, #2304) [Link]

Compilation may be slower (although not compilation of the C subset -- guess what, Gcc uses the same code for both!)
Um, no it doesn't. The frontends are separate, the parser is distinct, there is no way you can say it uses the same code for both except insofar as it also uses the same code for Ada, Objective C and Fortran.

C, still?

Posted Sep 22, 2017 20:34 UTC (Fri) by vomlehn (guest, #45588) [Link] (3 responses)

This greybeard is really tired of this argument. It would nice to have a good object-oriented language for writing kernels. Linux has a fair amount code that is logically object oriented but which is limited to being expressed with some pretty horrible C syntax. However, C++ is not the solution. I don't know of a solution and I don't have the time to take this detour. Apparently nobody else does, either. So, C it is.

C, still?

Posted Sep 24, 2017 8:18 UTC (Sun) by ncm (guest, #165) [Link] (2 responses)

There is little of interest in "object-oriented" languages; very little of the benefit of coding in C++ (vs C) arises from object support in the language, and very little from syntactic convenience. If that were all, there would be hardly any point to switching.

It is about putting the type system to work performing logic at compile time, to generate code that is correct by construction. This is not something exotic; it is daily life for a C++ programmer.

C, still?

Posted Sep 24, 2017 21:36 UTC (Sun) by peter-b (guest, #66996) [Link] (1 responses)

> It is about putting the type system to work performing logic at compile time, to generate code that is correct by construction. This is not something exotic; it is daily life for a C++ programmer.

Alas, this paradigm of C++ programming is a relatively modern concept, which relies heavily on language features introduced in C++11 and more recently. Most C++ projects I've worked on in my career use C++ as "C plus classes", and the use of types-as-compile-time-assertions was a controversially innovative suggestion. It must be nice to work in an environment where this sort of "types for compile-time logic" approach is commonplace. :-)

C, still?

Posted Sep 25, 2017 2:26 UTC (Mon) by ncm (guest, #165) [Link]

It really is.

MongoDB's core server engineering organization is very well-run. (And is hiring.) We are using C++14 for the current release, probably C++17 in the next.


Copyright © 2025, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds