ccode中的c:函数的重新声明必须具有可重载属性错误

时间:2016-12-20 18:32:28

标签: c xcode

当我在终端中使用gcc(带-Wall -Werror标志)运行我的C代码时,它没有给我任何错误。但是,当我在Xcode中运行我的代码时,它只给出了两个函数的上述错误。发生了什么事?

的main.c

#include "canvas.h"
#include "paint.h"
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

void program_loop(Canvas * canvas) {
    // ...
}

int main(int argc, char ** argv) {
    // ...
    return 0;
}

canvas.h

#ifndef CANVAS_H
#define CANVAS_H

typedef struct {
    // ...
} Canvas;

void create_canvas(Canvas * canvas, int row_num, int col_num);
void print_canvas(Canvas * canvas);
void write(Canvas * canvas); // "Previous overload of function is here."
void write_horizontal(Canvas * canvas, int row, int start_column, int end_column);
void write_vertical(Canvas * canvas, int start_row, int end_row, int column);
void write_right_diagonal(Canvas * canvas, int start_row, int end_row, int start_column, int end_column);
void write_left_diagonal(Canvas * canvas, int start_row, int end_row, int start_column, int end_column);
void erase(Canvas * canvas); // "Previous overload of function is here."
void resize(Canvas * canvas);
void add(Canvas * canvas);
void del(Canvas * canvas);
void clear_canvas(Canvas * canvas);

#endif

canvas.c

#include "canvas.h"
#include <stdio.h>
#include <stdlib.h>

void create_canvas(Canvas * canvas, int row_num, int col_num) {
    // ...
}

void print_canvas(Canvas * canvas) {
    // ...
}

void write(Canvas * canvas) { // Error here.
    // ...
}

void write_horizontal(Canvas * canvas, int row, int start_column, int end_column) {
    // ...
}

void write_vertical(Canvas * canvas, int start_row, int end_row, int column) {
    // ...
}

void write_right_diagonal(Canvas * canvas, int start_row, int end_row, int start_column, int end_column) {
    // ...
}

void write_left_diagonal(Canvas * canvas, int start_row, int end_row, int start_column, int end_column) {
    // ...
}

void erase(Canvas * canvas) { // Error here.
    // ...
}

void resize(Canvas * canvas) {
    // ...
}

void add(Canvas * canvas) {
    // ...
}

void del(Canvas * canvas) {
    // ...
}

void clear_canvas(Canvas * canvas) {
    // ...
}

paint.h

#ifndef PAINT_H
#define PAINT_H

#include "canvas.h"

// ...

#endif

paint.c

#include "paint.h"
#include <stdio.h>
#include <stdlib.h>

// ...

错误发生在void write(Canvas * canvas)和void erase(Canvas * canvas)函数中。任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:2)

首先,请注意write(可能erase)已在某些系统标头中定义。具体来说,在unistd.h中,有:

ssize_t write(int __fd, const void * __buf, size_t __nbyte)

在这个question中,我们发现重载在C中没有开箱即用。所以,在这里你有两个不同类型的write不同的函数,其中普通的C没有&#39;支持。

现在,我们有一个特殊的情况,当你在命令行通过clang进行编译时它可以工作:

clang -c canvas.c

没有得到错误,但是你可以通过Xcode。好吧,在Xcode中你可以查看Xcode执行的实际编译命令,对我来说看起来像是:

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang
-x c -arch x86_64 -fmessage-length=0
-fdiagnostics-show-note-include-stack -fmacro-backtrace-limit=0
-std=gnu99 -fmodules -gmodules
-fmodules-cache-path=/Users/donaldpinckney/Library/Developer/Xcode/DerivedData/ModuleCache
-fmodules-prune-interval=86400 -fmodules-prune-after=345600
-fbuild-session-file=/Users/donaldpinckney/Library/Developer/Xcode/DerivedData/ModuleCache/Session.modulevalidation
-fmodules-validate-once-per-build-session
-Wnon-modular-include-in-framework-module
-Werror=non-modular-include-in-framework-module -Wno-trigraphs
-fpascal-strings -O0 -fno-common -Wno-missing-field-initializers
-Wno-missing-prototypes -Werror=return-type -Wdocumentation
-Wunreachable-code -Werror=deprecated-objc-isa-usage
-Werror=objc-root-class -Wno-missing-braces -Wparentheses -Wswitch
-Wunused-function -Wno-unused-label -Wno-unused-parameter
-Wunused-variable -Wunused-value -Wempty-body
-Wconditional-uninitialized -Wno-unknown-pragmas -Wno-shadow
-Wno-four-char-constants -Wno-conversion -Wconstant-conversion
-Wint-conversion -Wbool-conversion -Wenum-conversion
-Wshorten-64-to-32 -Wpointer-sign -Wno-newline-eof -DDEBUG=1 -isysroot
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk
-fasm-blocks -fstrict-aliasing -Wdeprecated-declarations
-mmacosx-version-min=10.12 -g -Wno-sign-conversion
-Winfinite-recursion -iquote
/Users/donaldpinckney/Library/Developer/Xcode/DerivedData/paint-fovqgkhrrknzbxemgzpydqtwbtge/Build/Intermediates/paint.build/Debug/paint.build/paint-generated-files.hmap
-I/Users/donaldpinckney/Library/Developer/Xcode/DerivedData/paint-fovqgkhrrknzbxemgzpydqtwbtge/Build/Intermediates/paint.build/Debug/paint.build/paint-own-target-headers.hmap
-I/Users/donaldpinckney/Library/Developer/Xcode/DerivedData/paint-fovqgkhrrknzbxemgzpydqtwbtge/Build/Intermediates/paint.build/Debug/paint.build/paint-all-target-headers.hmap
-iquote
/Users/donaldpinckney/Library/Developer/Xcode/DerivedData/paint-fovqgkhrrknzbxemgzpydqtwbtge/Build/Intermediates/paint.build/Debug/paint.build/paint-project-headers.hmap
-I/Users/donaldpinckney/Library/Developer/Xcode/DerivedData/paint-fovqgkhrrknzbxemgzpydqtwbtge/Build/Products/Debug/include
-I/Users/donaldpinckney/Library/Developer/Xcode/DerivedData/paint-fovqgkhrrknzbxemgzpydqtwbtge/Build/Intermediates/paint.build/Debug/paint.build/DerivedSources/x86_64
-I/Users/donaldpinckney/Library/Developer/Xcode/DerivedData/paint-fovqgkhrrknzbxemgzpydqtwbtge/Build/Intermediates/paint.build/Debug/paint.build/DerivedSources
-F/Users/donaldpinckney/Library/Developer/Xcode/DerivedData/paint-fovqgkhrrknzbxemgzpydqtwbtge/Build/Products/Debug
-MMD -MT dependencies -MF
/Users/donaldpinckney/Library/Developer/Xcode/DerivedData/paint-fovqgkhrrknzbxemgzpydqtwbtge/Build/Intermediates/paint.build/Debug/paint.build/Objects-normal/x86_64/canvas.d
--serialize-diagnostics
/Users/donaldpinckney/Library/Developer/Xcode/DerivedData/paint-fovqgkhrrknzbxemgzpydqtwbtge/Build/Intermediates/paint.build/Debug/paint.build/Objects-normal/x86_64/canvas.dia
-c /Users/donaldpinckney/Stack/paint/canvas.c -o
/Users/donaldpinckney/Library/Developer/Xcode/DerivedData/paint-fovqgkhrrknzbxemgzpydqtwbtge/Build/Intermediates/paint.build/Debug/paint.build/Objects-normal/x86_64/canvas.o

这告诉我们,虽然Xcode使用了Clang,但它还使用了比-Wall -Werror更多的选项。此案例的重要标志是-fmodules,它启用modules的Clang语言功能。这将改变Xcode包含系统库的方式。我不知道为什么这会导致错误,但确实如此。您可以通过运行以下来测试:

clang -fmodules -c canvas.c

你会得到同样的错误。

要解决此问题,您可以执行以下两项操作之一:

  1. 将这些功能重命名为其他功能。
  2. 使用Clang overloadable attribute,如下所示:
  3. canvas.h:

    // ...
    void __attribute__((overloadable)) write(Canvas * canvas);
    // ...
    

    <强> canvas.c:

    // ...
    void __attribute__((overloadable)) write(Canvas * canvas) {
      // ...
    }
    // ..
    

答案 1 :(得分:0)

除了Donald Pinckney answer中的解决方案之外,您还可以通过关闭项目构建设置中的“启用模块(C和Objective-C)”来告诉Xcode关闭-fmodules(设置可以通过搜索“fmodules”找到。