Live data from Hacker News

Is the preprocessor still needed in C++? (2017)

foonathan.net

31–40 of 65 posts

Re: Is the preprocessor still needed in C++? (2017)

#32
post #19

Earlier quoted context omitted.

Template instantiation is a simple text replacement tool and it seems to work just fine.

https://github.com/dlang/dmd/blob/master/src/dmd/dtemplate.d That must be why the implementation of D's templates, which are designed to be easier to implement than C++'s is at least 8337 lines? edit: Clang's clocks in at about 11k lines (.cpp alone), I'm too scared to find out for GCC.

GCC's cp/pt.c is around 30k lines. But I don't expect the implementation of templates to be this localized, sure, most of it is probably in that module, but a lot will be strewn about the code base, too.

Re: Is the preprocessor still needed in C++? (2017)

#33
post #29

The best thing about C++ preprocessor is that it is dumb. Text goes in, text goes out. Easy to debug, simple rules. Anything I saw as an alternative either requires a significant amount of code, bending C++ rules, or specialized tools to see what is going on. Java tried so hard to "do the right thing" by abolishing the preprocessor, and we ended up with another preprocessor called IDE, unnecessary code patterns, and…

On the other hand, the preprocessor is so dumb that having a normal variable or enum named "OK" or "STATUS" is a risk, even if all of your dependencies are clean. All it takes is a user to include your header and some header that #defines any name in your header to be something else.

So that means you really need to name your preprocessor symbols (and any other all-caps names, because that's the convention) in ways that probably won't collide. Like MYLIB_OK.

So it starts off dumb, but then you have to start layering on convention and defensive programming immediately. And it complicates entire other features of the language, naming constants and enumerated values especially.

Re: Is the preprocessor still needed in C++? (2017)

#34
post #13

TBH the length that C++ goes to replace every single use of the preprocessor "just because" is close to zealotry. Every single "fix" probably requires more lines of code under the hood than the entire preprocessor and in the end you have added tons of additional features to the language to fix problems that (often) don't need fixing. The preprocessor being a simple text replacement tool is a feature, not a bug, but l…

> TBH the length that C++ goes to replace every single use of the preprocessor "just because" is close to zealotry. This comment is short-sighted. Take for example C++'s use of include guards to use translation units instead of modules to just compile a damn file. No one in their right mind would argue in favour of a preprocessor with #include instead of proper modules if they were to develop a new programming langua…

IMHO #include for making declarations visible to other compilation units is the one big feature where ditching the preprocessors makes sense, at least in C++ where headers contain both declarations and implementation code (it's not as critical for C). Simply being able to include a file anywhere in the source is still useful (simply as a generic text-processing feature) so #include shouldn't be removed if sharing declarations if solved differently (for instance through a module system).

Same with #define, no harm in adding actual constants to the language since it's a simple, straightforward and expected feature. But that's no reason getting rid of #define because that's also useful as a catch-all text replacement which doesn't work on the language-level (and that's useful in many situations).

Re: Is the preprocessor still needed in C++? (2017)

#35

TBH the length that C++ goes to replace every single use of the preprocessor "just because" is close to zealotry. Every single "fix" probably requires more lines of code under the hood than the entire preprocessor and in the end you have added tons of additional features to the language to fix problems that (often) don't need fixing. The preprocessor being a simple text replacement tool is a feature, not a bug, but l…

The preprocessor is a big roadblock for C++ modules

Arguably that's a problem that C++ brought onto itself, because it "encourages" to put implementation details into headers (in the form of inline methods and template code). In C it's common to only put public interface declarations into headers which results in headers being much smaller and much faster to parse (that's why a module system is much more important for C++ than for C).

Re: Is the preprocessor still needed in C++? (2017)

#36
post #10

We just need an interpreter that can work on C++ files, supported by the standard. Something akin to the https://www.python.org/dev/peps/pep-0638/ Code generators/transformers are rare only because it's so hard to actually start. Too bad https://www.circle-lang.org never took off.

Isn’t that what templates and constexpr are?

To a degree, but templates and constexpr don't support a bunch of features like compile-time field enumeration and introspection + code generation.

For example, let's say I have a bunch of structs:

  struct GeoCoordinate {
    int lat, long;
  };

  struct GeoArea {
    std::vector perimeter;
  };

  struct Place {
    std::string name;
    std::string contact_number;
    GeoArea area;
  };
Now I need to serialize these structs into a format to be sent over the wire. Currently, I have a few choices:

1. Use an off-the-shelf library like protobuf (disclaimer: I work for Google). Then I have to convert my code to a protobuf definition and rely on its code generator to perform [de]serialization. I also have to hope that my library supports all the field definitions I need.

2. Write macros to define each field in each structure. These macros perform some arcane magicks that somehow create the necessary [de]serialization functions. These macros are difficult to write and maintain (or I find a library).

3. Manually define the methods myself. This is tedious, hard to maintain, and error prone.

What if I could write some code in C++ which could read the structure and generate the appropriate serialization code? Something like (syntax hypothetical):

  Serializable(Class) {
    std::string serialize() {
      std::string output;
      for (auto member : Class.members()) { // loop unrolled at compile time
        if (member.type == int) {
          output.append(std::format("{:10}"), member.get())
        } else if (member.type == std::string) {
          ...
        } else if (member.type == std::vector) {
          ...
        } else if (std::has_metaclass_v) {
          output.append(member.get().serialize());
        }
      }
    };
  };

Then I could annotate my classes with Serializable instead.

See https://www.youtube.com/watch?v=4AfRAVcThyA.

Re: Is the preprocessor still needed in C++? (2017)

#37
post #30

Missing the most important case: Some external library you need changes a function signature and you need to be able to compile against the old or the new library, eg: #if LIBVERSION >= 2 draw_point (2, 3, RED); #else set_color (RED); draw_point (2, 3); #endif This is actually a case where the C preprocessor would be useful in many more languages. OCaml has cppo which is like a better cpp and is very useful for solvi…

You can use "if constexpr" for that.

Re: Is the preprocessor still needed in C++? (2017)

#38

We just need an interpreter that can work on C++ files, supported by the standard. Something akin to the https://www.python.org/dev/peps/pep-0638/ Code generators/transformers are rare only because it's so hard to actually start. Too bad https://www.circle-lang.org never took off.

A few years ago Herb Sutter proposed Python-like metaclasses in C++ through compile-time code generation. Not sure if anything has been proposed for general use. https://www.youtube.com/watch?v=4AfRAVcThyA

Unreal Engine 4 creates C++ reflection classes by parsing the headers and some of their custom macros that you define for member variables & function.

It basicaly allows you full C++ reflection, but only for classes that you mark with the UE4 macros.

Re: Is the preprocessor still needed in C++? (2017)

#39

TBH the length that C++ goes to replace every single use of the preprocessor "just because" is close to zealotry. Every single "fix" probably requires more lines of code under the hood than the entire preprocessor and in the end you have added tons of additional features to the language to fix problems that (often) don't need fixing. The preprocessor being a simple text replacement tool is a feature, not a bug, but l…

The preprocessor is a big roadblock for C++ modules

Could you elaborate on that? Which features of preprocessor make it impossible to implement C++ modules?

Re: Is the preprocessor still needed in C++? (2017)

#40
post #37
post #30

Missing the most important case: Some external library you need changes a function signature and you need to be able to compile against the old or the new library, eg: #if LIBVERSION >= 2 draw_point (2, 3, RED); #else set_color (RED); draw_point (2, 3); #endif This is actually a case where the C preprocessor would be useful in many more languages. OCaml has cppo which is like a better cpp and is very useful for solvi…

You can use "if constexpr" for that.

Even though one or other branch of the if-statement won't be valid C++? How does it know that set_color is a function if it isn't defined anywhere?
Post reply on HN