可行的语言是否需要预处理器?

发布于 2024-10-04 16:07:35 字数 207 浏览 3 评论 0原文

C++ 预处理器到底有多有用?即使在 C# 中,它仍然具有一些功能,但我一直在考虑完全放弃它的使用,转而使用一种假设的未来语言。我猜想有些语言,比如 Java,即使没有这样的东西也能生存下来。没有预处理步骤的语言是否具有竞争力和可行性?用没有预处理器的语言编写的程序需要采取哪些步骤来模拟其功能,例如用于调试和发布代码的不同代码,以及这些与#ifdef DEBUG相比如何?

How useful is the C++ preprocessor, really? Even in C#, it still has some functionality, but I've been thinking of ditching its use altogether for a hypothetical future language. I guess that there are some languages like Java that survive without such a thing. Is a language without a preprocessing step competitive and viable? What steps do programs written in languages without a preprocessor take to emulate it's functionality, e.g. different code for debug and release code, and how do these compare to #ifdef DEBUG?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

莫多说 2024-10-11 16:07:35

事实上,大多数语言在没有预处理器的情况下处理得很好。我接着说,使用 C/C++ 预处理器的必要性源于它们缺乏几个部分的功能。

例如:

  • 大多数语言不需要头文件并包含防护,因为它们有“模块”的概念。
  • 条件编译可以通过static if或类似的机制轻松获得。
  • 与使用预处理器相比,几乎总是可以通过更明确的方式减少代码重复:使用模板/泛型、反射系统等。

所以我的结论是:对于大多数“功能”,您可以使用预处理器和元编程,存在一个更清晰的替代方案,它更安全、更方便使用。

D 编程语言作为一种编译型低级语言,是一个很好的例子,说明“如何提供通常通过预处理器完成的大多数功能” ,实际上没有预处理” - 包括我提到的所有内容,加上字符串混合和模板混合,以及可能其他一些通常通过 C/C++ 预处理解决的问题的巧妙解决方案。

In fact, most languages deal very well without a preprocessor. I'd move on to say that the necessity of using preprocessor with C/C++ roots in their lack of several parts of functionality.

For example:

  • Most languages don't need header files and include guards, because they have the notion of a "module".
  • Conditional compilation can be easily obtained through static ifs or an analogous mechanism.
  • Code repetition can almost always be reduced in more clear ways than what you can achieve with the preprocessor: using templates/generics, a reflection system, etc, etc.

So my conclusion is: for most "features" you can get with preprocessor and metaprogramming, a more clear alternative exists which is safer and more convenient to use.

The D programming language, as a compiled low-level language, is a nice example on "how to provide most features usually done via preprocessor, without actually preprocessing" - includes all I've mentioned, plus string mixins and template mixins, and probably some other clever solutions to problems usually solved with preprocessing in C/C++.

花伊自在美 2024-10-11 16:07:35

我想说不,宏对于一种语言的可行性和竞争力来说是不需要的。

这并不意味着某些语言不需要宏。

如果您需要宏,可能是因为您的语言存在缺陷。 (或者因为您试图与其他一些有缺陷的语言兼容,例如 C++ 与 C 兼容。:))。让语言“足够好”,你将很少需要宏,以至于语言可以不需要它们。

(当然,这取决于您的语言的目标是什么,“足够好”的实际含义是什么,以及宏是否是实现某些目标的好方法,或者只是弥补缺少概念/功能的创可贴。

)足够”的语言,可能仍然有奇怪的时候你希望宏在那里。也许它们仍然值得拥有。也许不是。取决于它们给语言带来了什么以及它们在复杂性方面引入了哪些问题(对编译器/运行时和程序员来说)。但任何语言功能都是如此。你不会以“拥有每一个功能”为目标来设计一种语言,所以你必须选择并使用它。根据权衡和利益进行选择。

例如,模板是 C++ 中非常强大的功能,我发现我在 C# 中偶尔会怀念一些功能,但 C# 应该拥有它们吗?每种语言都应该有这个功能吗?也许不会,考虑到它们带来的复杂性(事实上您通常可以使用 C++/CLI 来完成此类工作)。

顺便说一句,我并不是说“任何好的语言都没有宏”;而是说“任何好的语言都没有宏”。我只是说好的语言不需要它们。 FWIW,Java 没有它们曾经让我很恼火,但这可能是因为 Java 在某些领域缺乏,而不是因为宏是必不可少的。

I would say no, macros are not needed for a language to be viable and competitive.

That doesn't mean macros are not needed in some languages.

If you need macros it's probably because there is a deficiency in your language. (Or because you're trying to be compatible with some other deficient language, like C++ is with C. :)). Make the language "good enough" and you will need macros so rarely that the language can do without them.

(Of course, it depends what your language's goals are what "good enough" actually means, and whether or not macros are a good way to achieve certain things or just a band-aid for missing concepts/features.)

Even in a "good enough" language, there may still be the odd time where you wish macros were there. Maybe they would still be worth having. Maybe not. Depends on what they bring to the language and what problems they introduce in terms of complexity (to the compiler/runtime and to the programmer). But that is true of any language feature. You wouldn't design a language with the aim to "have every single feature" so you have to pick & choose based on the trade-offs and benefits.

e.g. Templates are a fantastically powerful feature in C++, and something I find I miss occasionally in C#, but should C# have them? Should every language have the feature? Perhaps not, given the complexity they would bring with them (and the fact you can usually use C++/CLI for that kind of work).

BTW, I'm not saying "any good language doesn't have macros"; I'm just saying a good language doesn't need them. And FWIW, it used to irritate me that Java didn't have them, but that was probably because Java was lacking in certain areas and not because macros are essential.

誰ツ都不明白 2024-10-11 16:07:35

它非常有用,但应小心使用。

几个你需要的例子。

  1. 目前,除了处理器之外,没有其他标准方法可以正确处理#include,因为它是标准的一部分。此外,您还需要 define 才能包含防护。但这是 C++ 特有的问题,在其他语言中不存在。
  2. 当您需要配置系统以使用不同的 API、不同操作系统的不同工具包时,处理器对于条件编译非常有用,这是唯一的方法(除非您想创建一个抽象接口,然后在构建系统级别进行条件编译) )。
  3. 使用当前的 C++ 标准 (2003),无需使用可变参数模板,在某些情况下可以让生活变得更加轻松。例如,当您需要创建一堆类时,例如:

    模板
    类函数 { ... }
    模板<类型名称 R,类型名称 T1>
    类函数 { ... }
    模板<类型名称 R,类型名称 T1,类型名称 T2>
    类函数 { ... }
    ...
    

    在当前的 C++ 标准中,如果没有处理器,几乎不可能正确完成此操作。 (在 C++0x 中,有可变参数模板使其变得更加容易)。

    事实上,像 boost::functionboost::signalboost::bind 这样的伟大工具需要相当多的
    复杂的模板处理,使这些东西可以与当前的编译器一起工作。

  4. 有时模板提供了非常好的结构,如果没有预处理器就不可能实现,例如:

    assert(ptr!=0);
    

    打印中止程序打印:

    <块引用>

    foo.cpp 第 134 行“ptr!=0”断言失败

    当然,它对于单元测试非常有用:

    TEST(3.14159 <=pi && pi < 3.141599);
    

    打印中止程序打印:

    <块引用>

    测试在 foo.cpp 第 134 行失败“3.14159 <=pi && pi <3.141599”

    有时,模板

  5. 记录。通常,使用宏更容易实现日志记录。为什么?

    您需要写:

    if(should_log(info))
       日志(信息)<< “这是文件 foo.cpp 第 10 行 foo::doit() 中的消息” << “价值是”<< x;
    

    或更简单:

    <前><代码>LOG_INFO() << “价值是”<< x;

    其中已经包括:文件、行号、函数名称和条件。非常有价值。

    事实上 boost::log apache 日志记录使用这样的东西。

是的...预处理器有时是邪恶的,但在很多情况下它非常有用,所以聪明地小心使用它就可以了。

但是,如果您用它实现:

  • 宏而不是内联函数。
  • 不可读且不清楚的宏来“减少代码”
  • 常量

你做错了。

底线

每个工具都可能被滥用(相信我,我见过非常疯狂的预处理器
滥用它的真实代码)但今天它是非常有用的东西。

It is very useful, however should be used with care.

Few examples where you need it.

  1. Currently there is no other standard way to handle #include properly other then processor as it a part of standard. Also you need define to have include guard. But this is very C++ specific issue that does not exist in other languages.
  2. Processor is very useful for conditional compilations when you need to configure your system to work with different API's, different OS's different toolkit, it is the only way to go (unless you want to create an abstract interfaces and then make conditional compilation on build system level).
  3. With current C++ standard (2003) without variadic templates it makes life much easier in certain situations. For example, when you need to create a bunch of classes like:

    template<typename R>
    class function<R()> { ... }
    template<typename R,typename T1>
    class function<R(T1)> { ... }
    template<typename R,typename T1,typename T2>
    class function<R(T1,T2)> { ... }
    ...
    

    It is almost impossible to do it properly without processor in current C++ standard. (in C++0x there is variadic templates that make it much easier).

    In fact great tools like boost::function, boost::signal, boost::bind require quite
    complicated templates handling to make this stuff work with current compilers.

  4. Sometimes templates provide very nice structures that are impossible without preprocessor, for example:

    assert(ptr!=0);
    

    That prints aborts the program printing:

    Assertion failed in foo.cpp, line 134 "ptr!=0"

    And of course it is really useful for unit testing:

    TEST(3.14159 <=pi && pi < 3.141599);
    

    That prints aborts the program printing:

    Test failed in foo.cpp, line 134 "3.14159 <=pi && pi < 3.141599"

  5. Logging. Usually logging is something much easier to implement with macros. Why?

    You need either to write:

    if(should_log(info))
       log(info) << "this is the message in file foo.cpp, line 10, foo::doit()" << "Value is " << x;
    

    or simpler:

    LOG_INFO() << "Value is " << x;
    

    Which includes already: file, line number, function name and condition. Very valuable.

    In fact boost::log apache logging use such things.

Yes... Preprocessor sometimes is evil, but it too many cases it is extremely useful, so use it smartly and with care and it is fine.

However if you implement with it:

  • Macros instead if inline function.
  • Unreadable and unclear macros to "reduce the code"
  • constants

You are do it wrong.

Bottom line

As every tool it can be abused (and beleive me I had seen very crazy preprocessor
abuse it real code) but today it is very useful thing.

萌逼全场 2024-10-11 16:07:35

您不需要预处理步骤来实现条件编译。你并不真正需要宏(没有字符串化和标记粘贴运算符也可以,甚至这些也可以在没有 PP 的情况下完成)。 #includes 是一种非常特殊的噩梦,它对引用调用的建模都是错误的。

还有什么如此重要?

You do not need preprocessing step to implement conditional compilation. You do not really need macros (one can live without stringize and token-paste operators, and even these could be done without PP). #includes are a very special kind of nightmare, which models the reference invocation all wrong.

What else is so important?

笔芯 2024-10-11 16:07:35

这取决于你认为“可行”的是什么,但是
在 C++ 中,模板、内联和命名空间等功能已经消除了使用宏的许多必要性/可取性。我发现自己在 C++ 中使用宏的唯一原因是与 C 集成(标头和处理定义中的 #ifdef __cplusplus)。对于其他语言,使用 JNI 或 SWIG 等工具来生成 C 头文件/库是不必要的。

与使用宏来控制“debug”和“nodebug”构建相比,编译器包含一个调试编译选项来包含/启用必要的功能更有意义。

有几种语言不需要宏就可以工作;如果您正在寻找类似 C 的语言进行比较,我建议 D http:// /www.digitalmars.com/d/2.0/comparison.html

It would depend upon what you consider 'viable', but
In C++, a lot of the necessity for/desirability of using macros has been obviated by features such as templates, inlining and namespaces. The only reason I find myself using macros in C++ is for integration with C (#ifdef __cplusplus in headers and processing definitions). With other languages, this is unnecessary with tools like JNI or SWIG to generate C headers/libraries.

Rather than use macros to control 'debug' and 'nodebug' builds, it would make more sense for the compiler to include a debug compile option to include/enable the necessary features.

Several languages just work without macros; if you're looking for a C-like language to compare with, I suggest D http://www.digitalmars.com/d/2.0/comparison.html

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文