V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
douglas1997
V2EX  ›  问与答

C++程序到底是如何编译的,真的是先将其翻译成 C 程序?

  •  
  •   douglas1997 · 2017-09-11 20:44:05 +08:00 · 2410 次点击
    这是一个创建于 2428 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在上 coursea 的 C++课程,颠覆了以前 C 编程中的看法。

    #include <iostream>
    using namespace std;
    class A{
        int i;
        public:
            void Hello(){ cout << "hello" << endl; }
    };
    int main(){
        A * p = NULL;
        p->Hello();
        return 0;
    }
    

    这玩意的编译输出是 hello。这样真的好吗。。。

    13 条回复    2017-09-12 07:17:11 +08:00
    zts1993
        1
    zts1993  
       2017-09-11 20:53:28 +08:00
    这个有点颠覆我的认知: 这个不会 core 么??
    jlsk
        2
    jlsk  
       2017-09-11 21:04:35 +08:00
    正常,你把 Hello()改成 cout <<i<< endl;就知道错了
    03
        3
    03  
       2017-09-11 21:07:55 +08:00
    对于标题:这都什么时候的事情了

    https://stackoverflow.com/questions/2505328/calling-class-method-through-null-class-pointer 一样

    这样很好啊,反正你的 Hello()不与具体对象相关,直接就解释为调用那个函数不就可以了,反正对一个无效指针调用是你的责任而不是 C++有义务检查
    douglas1997
        4
    douglas1997  
    OP
       2017-09-11 21:14:17 +08:00
    @jlsk 这个我知道,关键是这样去实现是不是不太好?(不太直觉)
    douglas1997
        5
    douglas1997  
    OP
       2017-09-11 21:18:44 +08:00
    @zts1993 不 core 不 core hhh
    zmj1316
        6
    zmj1316  
       2017-09-11 21:28:11 +08:00
    这个和 C 有什么关系...虽然传进去的 this 是个 null ,反正又没调用到,你的函数要是个虚函数应该就跪了
    acros
        7
    acros  
       2017-09-11 21:34:27 +08:00 via iPhone
    为啥会有这种写法,是为了教学说明类的内存布局吧?
    secondwtq
        8
    secondwtq  
       2017-09-11 21:36:32 +08:00   ❤️ 3
    如果你对 C++ 足够熟悉,那么你可以以相对直接的方式把 C++ 程序翻译成等效的 C 程序。最早的 C++ 编译器就是这么干的。
    之所以强调 相对直接,是因为在 Compiler 中,C 语言实际上相当于高级汇编,最近几年比较流行 codegen 编译到 LLVM IR,实际上更早的时候有不少是编译到 C 语言的,比如 GHC 最后一层的 IR 叫 C--,Gnome 的 Vala 也是这么干的
    如果不计较这个编译过程的逻辑和复杂性,以及运行时系统的介入程度的话,JS 都可以编译到 C。对于 C++ 自己的体量和设计来说,翻译到 C 的过程(尤其是楼主所用的这个子集)是相对直接的。
    详见 https://isocpp.org/wiki/faq/compiler-dependencies#convert-to-c

    对于一个要与 C 争市场的语言来说,“这么实现”是完全没问题的。“不太好”的反而在于楼主的用法,一般 C++ 不提倡 hack,尤其是这种会 UB 的 hack。

    建议楼主可以多看看出来的汇编,还有 Inside the C++ Object Model 这种书,了解了一个特性,可以多想一步这个是怎么实现的。

    这里其实有一个坑。学一门语言,我认为最重要的是一方面学它的 principle,另一方面学 application。楼主有必要在学之前了解一下 C++ 的一些基本的特点,很简单:directly mapped to hardware, 还有 zero cost abstraction。楼主如果单一地照这条路走下去,很有可能会只记得前者,而忘了后者。因为 C++ 是以 directly mapped to hardware 以及与 C 语言兼容(至少是一开始)为原则而设计的,所以可以相对简单地翻译成 C 语言,但是不代表你把 C++ 代码翻译成 C 代码没问题了,C++ 代码就没问题了。如果不明白 abstraction 那一部分,那实际上没有太多用 C++ 的意义。

    如果发现自己在问 std::optional 有什么意义,Template Metaprogramming 有什么用这种问题的时候,说明该去学 Haskell 压压惊了(逃
    acros
        9
    acros  
       2017-09-11 21:37:53 +08:00 via iPhone
    另外你说这个反直觉我认可,颠覆 c 的认识? hmmmm 看来没见过 c 里面,0 地址强转 struct 指针求成员 offset 的那个方法。
    gamexg
        10
    gamexg  
       2017-09-11 22:11:11 +08:00 via Android
    go 这样干也行,也是你只要不访问成员变量随你玩,访问了就,来😇了
    admos
        11
    admos  
       2017-09-11 22:31:04 +08:00 via iPhone
    这东西各种都是 trival 的,是 POD 类型的按 c 来怎么了,还省了各种乱七八糟的呢。
    douglas1997
        12
    douglas1997  
    OP
       2017-09-11 23:18:08 +08:00 via iPhone
    @secondwtq 非常感谢前辈指导。
    geelaw
        13
    geelaw  
       2017-09-12 07:17:11 +08:00
    这个程序的行为不是确定的啊,因为里面有 UB,编译器可以产生一个什么都不干的程序,也可以产生恰好输出 Hello 的程序。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   835 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 38ms · UTC 22:31 · PVG 06:31 · LAX 15:31 · JFK 18:31
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.