我们来分析一下下面的代码示例:
int main() {
return func();
}
int func() {
return 1;
}
Clang 会报错:
/private/tmp/src.cpp:2,9 - Error - use of undeclared identifier 'func'
但是我可以在广泛使用的示例中找到很多此类错误,例如一些arduino来源: https://github.com/firmata/arduino/blob/master/examples/StandardFirmata/StandardFirmata.ino
line 235 : disableI2CPins(); // invocation (before definition, no declaration before)
...
line 651 : void disableI2CPins() { .. } // definition
虽然函数是在定义之前使用的,但是代码可以用GCC成功编译。怎么会这样呢? Clang 和 GCC 的行为有什么不同吗?是否有任何标志允许 Clang 这样做?
PS。以下是编译 Arduino IDE 使用的代码的成功命令行:/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -mmcu=atmega2560 -DF_CPU=16000000L -DARDUINO=10600 -DARDUINO_AVR_MEGA2560 -DARDUINO_ARCH_AVR -I/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/avr/cores/arduino -I/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/avr/variants/mega -I/Applications/Arduino.app/Contents/Resources/Java/libraries/Servo/src -I/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/avr/libraries/Wire -I/Applications/Arduino.app/Contents/Resources/Java/libraries/Firmata/src /var/folders/64/fwfkm1k51zbd4_c5lwpsbljh0000gn/T/build8049651108713091801.tmp/StandardFirmata.cpp -o /var/folders/64/fwfkm1k51zbd4_c5lwpsbljh0000gn/T/build8049651108713091801.tmp/StandardFirmata.cpp.o
最佳答案
这实际上与编译器无关,而是与Arduino IDE有关。 IDE 有一个预处理步骤,可以前向声明所有已定义的函数,这样您就无需担心函数在文件中的位置。
我强烈建议您遵循语言规则并在使用函数之前预先声明或定义它们。您的代码将更加可移植和易于理解。
关于c++ - Clang 和 GCC 在定义之前对函数调用的诊断行为不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33629558/