编程原理与实践第2章第8章钻1

时间:2017-09-10 18:17:25

标签: c++ clang++

问题:

我无法获得作者提供的代码,通过Bjarne Stroustrup编写的“原则与实践”第8章中的clang ++进行链接。

代码:

 ~/scratch/cpp/chp8 (09/10/2017-13:51:43[EDT]) cat my.cpp
#include <iostream>
#include "my.h"
void print_foo() { std::cout << foo << std::endl; }
void print(int i) { std::cout << i << std::endl; }

 ~/scratch/cpp/chp8 (09/10/2017-13:52:29[EDT]) cat my.h
#ifndef MY_H
#define MY_H
extern int foo;
void print_foo();
void print(int);
#endif

 ~/scratch/cpp/chp8 (09/10/2017-13:52:33[EDT]) cat use.cpp
#include "my.h"

int main() {
  foo = 7;
  print_foo();
  print(99);
  return 0;
}

尝试:

我尝试了几种不同的编译方式:

一个 - 编译包含主要功能的驱动程序应用。

 ~/scratch/cpp/chp8 (09/10/2017-13:52:39[EDT]) clang++ -std=c++14 -stdlib=libc++  use.cpp -o use.cpp.o
Undefined symbols for architecture x86_64:
  "print(int)", referenced from:
      _main in use-2864c4.o
  "print_foo()", referenced from:
      _main in use-2864c4.o
  "_foo", referenced from:
      _main in use-2864c4.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

两个 - 专门编译my.cpp文件而不是链接。虽然我成功编译了,但我不确定如何将use.cpp与此目标文件链接起来。

 ~/scratch/cpp/chp8 (09/10/2017-14:09:40[EDT]) clang++ -std=c++14 -stdlib=libc++ -c my.cpp -o my.cpp.o

- 使用所有.cpp文件。

 ~/scratch/cpp/chp8 (09/10/2017-14:15:32[EDT]) clang++ -std=c++14 -stdlib=libc++ my.cpp use.cpp
Undefined symbols for architecture x86_64:
  "_foo", referenced from:
      print_foo() in my-2243d1.o
      _main in use-796f91.o
     (maybe you meant: __Z9print_foov)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

问题:

除了我做错了什么这个显而易见的问题之外,我对我错过了什么或对这里的理解不感兴趣?

注意:

我没有在我应该或不应该做的事情上寻找个人意见或偏好。这是一本纯粹的教育冒险,我正在阅读这本书,我想保留它。

其它

 ~/scratch/cpp/chp8 (09/10/2017-14:15:25[EDT]) uname -a
Darwin abes-MacBook-Pro.local 16.7.0 Darwin Kernel Version 16.7.0: Thu Jun 15 17:36:27 PDT 2017; root:xnu-3789.70.16~2/RELEASE_X86_64 x86_64
 ~/scratch/cpp/chp8 (09/10/2017-14:15:28[EDT]) clang++ -v
Apple LLVM version 8.1.0 (clang-802.0.42)
Target: x86_64-apple-darwin16.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

1 个答案:

答案 0 :(得分:1)

您获得的错误与编译和链接之间的差异无关。而是代码中存在错误。出错的原因是您声明全局变量foo,但您从未定义它。您需要添加行

int foo = 0;

到你的一个.cpp文件中。这可能在my.cpp中最有意义。

请注意,使用像这样的全局变量被视为编码恐怖。你不应该在实际代码中这样做。

关于编译和链接:

从C ++创建可执行文件需要几个步骤。在这里,我们将讨论编译与链接以及如何手动执行这些步骤。还有其他步骤,但我不会在这里介绍它们。

首先,您可以一次编译和链接所有源文件:

$ clang++ -std=c++14 -stdlib=libc++ my.cpp use.cpp

我很困惑为什么这不适用于你的“尝试三”。我将在稍后对此进行研究。

要手动编译和链接源代码,您可以执行以下操作:

$ clang++ -std=c++14 -stdlib=libc++ -c my.cpp -o my.o
$ clang++ -std=c++14 -stdlib=libc++ -c use.cpp -o use.o
$ clang++ -std=c++14 -stdlib=libc++ my.o use.o -o use

请注意,我将my.cpp编译为my.o而不是my.cpp.o。这是常见的惯例。

此外,一旦您对这些概念感到满意,我强烈建议您使用诸如make之类的构建工具或自动管理这些步骤的XCode项目。