【问题标题】:Advanced C and C++ compiling: unable to compile the example program mentioned in the book高级C和C++编译:无法编译书中提到的示例程序
【发布时间】:2015-01-13 20:32:12
【问题描述】:

我正在阅读 Milan Stevanovic 的《高级 C 和 C++ 编译》一书

以下是书中的快照,然后是我面临的问题。


概念图:演示项目

用于构建这个简单项目的开发环境将基于运行在 Linux。清单 2-1 到 2-3 包含演示项目中使用的代码。

清单 2-1。 function.h

#pragma once
#define FIRST_OPTION
#ifdef FIRST_OPTION
#define MULTIPLIER (3.0)
#else
#define MULTIPLIER (2.0)
#endif

float add_and_multiply(float x, float y);

清单 2-2。 function.c

int nCompletionStatus = 0;
float add(float x, float y)
{
    float z = x + y;
    return z;
}
float add_and_multiply(float x, float y)
{
    float z = add(x,y);
    z *= MULTIPLIER;
    return z;
}

清单 2-3。 main.c

#include "function.h"
extern int nCompletionStatus = 0;
int main(int argc, char* argv[])
{
    float x = 1.0;
    float y = 5.0;
    float z;
    z = add_and_multiply(x,y);
    nCompletionStatus = 1;
    return 0;
}

演示项目预处理示例:

gcc编译器提供了只对输入源文件进行预处理阶段的模式:

gcc -i <input file> -o <output preprocessed file>.i

除非另有说明,预处理器的输出是与输入文件同名的文件,并且 其文件扩展名为.i。对文件function.c运行预处理器的结果如清单2-4所示。

清单 2-4。 function.i

# 1 "function.c"
# 1 "
# 1 "
# 1 "function.h" 1
# 11 "function.h"
float add_and_multiply(float x, float y);
# 2 "function.c" 2
int nCompletionStatus = 0;
float add(float x, float y)
{
    float z = x + y;
    return z;
}
float add_and_multiply(float x, float y)
{
    float z = add(x,y);
    z *= MULTIPLIER;
    return z;
}

如果向 gcc 传递很少的额外标志,则可以获得更紧凑和更有意义的预处理器输出,例如

gcc -E -P -i <input file> -o <output preprocessed file>.i

这会产生如清单 2-5 所示的预处理文件。

清单 2-5。 function.i(精简版)

float add_and_multiply(float x, float y);
int nCompletionStatus = 0;
float add(float x, float y)
{
    float z = x + y;
    return z;
}
float add_and_multiply(float x, float y)
{
    float z = add(x,y);
    z *= 3.0;
    return z;
}

很明显,预处理器替换了符号MULTIPLIER,其实际值是基于以下事实: USE_FIRST_OPTION 变量已定义,最终为 3.0


问题:

当我使用 gcc 编译程序时,以下是我面临的错误 来自我的终端的快照。

gcc -i function.c -o function.i
cc1: error: unrecognized command line option '-i'

gcc function.c -o function.i
/usr/lib/gcc/i686-linux-gnu/4.6/../../../i386-linux-gnu/crt1.o:
In function '_start':
(.text+0x18): undefined reference to 'main'
collect2: ld returned 1 exit status

$pwd
/home/adminuser/advance_compiling
$ll
total 20
drwxrwxr-x  2 adminuser adminuser 4096 Jan 10 23:51 ./
drwxr-xr-x 26 adminuser adminuser 4096 Jan 10 23:57 ../
-rw-rw-r--  1 adminuser adminuser  216 Nov 15 08:58 function.c
-rw-rw-r--  1 adminuser adminuser  163 Jan 10 23:33 function.h
-rw-rw-r--  1 adminuser adminuser  257 Dec 28 06:46 main.c

我如何摆脱这种情况并继续学习课程? 请提出建议。

【问题讨论】:

  • 这个gcc -E -P -i &lt;input file&gt; -o &lt;output preprocessed file&gt;.i真的是书上的吗?
  • 您错过了一个学习如何查找要使用的正确标志的绝佳机会。
  • 是的gcc -E -P -i &lt;input file&gt; -o &lt;output preprocessed file&gt;是书上的吗?
  • 您应该尝试过gcc --helpman gcc 或阅读Invoking GCC - 比在这里提问更快
  • 书上确实有,应该是错了。

标签: c++ c linux gcc compiler-errors


【解决方案1】:

-i 不是一个有效的命令行选项——我不确定这本书是从哪里得到的。为了只运行预处理器,您应该改用选项-E

【讨论】:

  • 也许书使用的编译器与 gcc 不同
  • 这是我的第一个想法,但问题中的文字似乎是直接从书中引用的。
  • 我很困惑,因为 OP 发布了预处理文件,我以为他想编译代码,而不是在上面运行预处理器,我以为他在这一步成功了,但无论如何 @ 987654323@从哪里来?如果它来自书中,可能在 gcc 的早期版本中有效。
  • 我刚刚在 Google 图书中查找过,这绝对是该书的直接引述。它也是不到一年前发布的,所以旧版本的 GCC 不是罪魁祸首。 (并不是说我认为他们会改变这样的主要旗帜。)谁知道......
  • 这有点像我倾向于的,没有阅读更多的书来看看它是否解释了环境是如何设置的。但是对于一本教科书来说非常草率。我注意到发布者的页面有提交勘误表的方法,也许我稍后会在那里发表评论。
【解决方案2】:

我是这本书的技术审稿人,作者要求我代表他发表这个解释:

您发现的错误确实是一个错误,在书籍校对/编辑的后期引入。抱歉踩了它+书籍勘误表仍未打印出来(很快就会发生)。

【讨论】:

  • 本书勘误表现在可用吗?
【解决方案3】:

试试这个

gcc -E -P function.c -o function.i

没有-i 选项,它就不是gcc 选项。

注意:这个答案是在我意识到误解了这个问题之后才修复的,所以我决定保留它而不是删除它,但是 Katie 在我之前回答了它做了。

【讨论】:

    【解决方案4】:

    从本书示例中的.i 输出文件判断,错误似乎出在实用程序本身。

    不要使用gcc,而是使用cpp。 gcc 在底层使用 cpp(C 预处理器)来处理宏扩展和头文件包含。 cpp 的输出是一个.i 用于c 源代码的文件和.ii 用于c++。

    cpp function.c > function.i
    

    【讨论】:

      【解决方案5】:

      试试下面的代码:

      function.c
      
      #include "function.h"
      int nCompletionStatus = 0;
      float add(float x, float y)
      {
          float z = x + y;
          return z;
      }
      float add_and_multiply(float x, float y)
      {
          float z = add(x,y);
          z *= MULTIPLIER;
          return z;
      }
      
      main.c
      
          //#include "function.h"
          extern int nCompletionStatus;
          int main(int argc, char* argv[])
          {
              float x = 1.0;
              float y = 5.0;
              float z;
              z = add_and_multiply(x,y);
              nCompletionStatus = 1;
              return 0;
          }
      
      Now execute:
      gcc function.c main.c
      
      otherwise 
      gcc -c function.c
      gcc function.o main.c
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-03-30
        • 1970-01-01
        • 1970-01-01
        • 2017-02-20
        • 1970-01-01
        • 1970-01-01
        • 2018-07-13
        • 2013-10-08
        相关资源
        最近更新 更多