Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 叮当格式能破坏我的代码吗?_C_Clang Format - Fatal编程技术网

C 叮当格式能破坏我的代码吗?

C 叮当格式能破坏我的代码吗?,c,clang-format,C,Clang Format,由于clangformat是一种仅用于重新格式化代码的工具,这种格式化是否可能会破坏工作代码,或者至少会改变其工作方式?是否存在某种合同,它将/不能改变代码的工作方式 我们有很多代码需要使用clangformat进行格式化。这意味着,许多代码行将发生更改。不必检查每一行只因铿锵格式而更改的代码,这将大大简化此过程 我想说,clangformat不会改变代码的工作方式。另一方面,如果这可以保证,我不能100%肯定。我想它不会,因为它是建立在clang的静态分析基础上的,因此了解代码本身的结构,而不

由于
clangformat
是一种仅用于重新格式化代码的工具,这种格式化是否可能会破坏工作代码,或者至少会改变其工作方式?是否存在某种合同,它将/不能改变代码的工作方式

我们有很多代码需要使用
clangformat
进行格式化。这意味着,许多代码行将发生更改。不必检查每一行只因
铿锵格式而更改的代码,这将大大简化此过程


我想说,
clangformat
不会改变代码的工作方式。另一方面,如果这可以保证,我不能100%肯定。

我想它不会,因为它是建立在clang的静态分析基础上的,因此了解代码本身的结构,而不仅仅是一个只对文本进行操作的愚蠢的源代码格式化程序(能够使用编译器库的好处之一)。假设格式化程序使用与编译器本身相同的解析器和lexer,我会感到足够安全,这样它就不会出现任何问题,即吐出与您提供给它的行为相同的代码


这里可以看到C++格式化程序的源代码:

< p>因为 CLAN格式只影响空白字符,您可以检查代码之前和之后的代码> CLAN格式< /代码> ING与空白相同。在Linux/BSD/OS X中,您可以使用
diff
tr
来实现:

$ diff --ignore-all-space <(tr '\n' ' ' < 2.c ) <(tr '\n' ' ' < 1.c)

$diff——忽略所有空格,确保它可以更改代码的工作方式。原因是C程序可以查看其源代码的某些属性。我想的是
\uuuu LINE\uuuu
宏,但我不确定是否还有其他方法

考虑
1.c

#include <stdio.h>
int main(){printf("%d\n", __LINE__);}
In file included from restyled.c:1:
./MyStruct.h:2:5: error: unknown type name 'uint8_t'
    uint8_t value;
    ^
1 error generated.
现在执行一些
clangformat

> clang-format -style=Chromium 1.c >2.c
2.c
是:

#include <stdio.h>
int main() {
  printf("%d\n", __LINE__);
}
简短回答:是的。
clangformat
工具有一个
-sort includes
选项。更改
#include
指令的顺序肯定会改变现有代码的行为,可能会破坏现有代码。

由于一些内置样式将相应的
SortIncludes
选项设置为
true
,因此
clangformat
是否会对您的包含重新排序可能并不明显

MyStruct.h:

struct MyStruct {
    uint8_t value;
};
#include <stdint.h>
#include <stddef.h>
#include "MyStruct.h"

int main (int argc, char **argv) {
    struct MyStruct s = { 0 };
    return s.value;
}
#include "MyStruct.h"
#include <stddef.h>
#include <stdint.h>

int main(int argc, char **argv) {
  struct MyStruct s = {0};
  return s.value;
}
#include <stdint.h>
#include <stddef.h>

#include "MyStruct.h"

int main (int argc, char **argv) {
    struct MyStruct s = { 0 };
    return s.value;
}
#include <stddef.h>
#include <stdint.h>

#include "MyStruct.h"

int main(int argc, char **argv) {
  struct MyStruct s = {0};
  return s.value;
}
#include <stdint.h>
#include <stddef.h>
// must come after stdint.h
#include "MyStruct.h"

int main (int argc, char **argv) {
    struct MyStruct s = { 0 };
    return s.value;
}
原件。c:

struct MyStruct {
    uint8_t value;
};
#include <stdint.h>
#include <stddef.h>
#include "MyStruct.h"

int main (int argc, char **argv) {
    struct MyStruct s = { 0 };
    return s.value;
}
#include "MyStruct.h"
#include <stddef.h>
#include <stdint.h>

int main(int argc, char **argv) {
  struct MyStruct s = {0};
  return s.value;
}
#include <stdint.h>
#include <stddef.h>

#include "MyStruct.h"

int main (int argc, char **argv) {
    struct MyStruct s = { 0 };
    return s.value;
}
#include <stddef.h>
#include <stdint.h>

#include "MyStruct.h"

int main(int argc, char **argv) {
  struct MyStruct s = {0};
  return s.value;
}
#include <stdint.h>
#include <stddef.h>
// must come after stdint.h
#include "MyStruct.h"

int main (int argc, char **argv) {
    struct MyStruct s = { 0 };
    return s.value;
}
由于头文件的重新排序,我在编译
restyled.c
时遇到以下错误:

#include <stdio.h>
int main(){printf("%d\n", __LINE__);}
In file included from restyled.c:1:
./MyStruct.h:2:5: error: unknown type name 'uint8_t'
    uint8_t value;
    ^
1 error generated.
然而,这个问题应该很容易解决。不太可能有这样的顺序相关包含,但是如果有,可以通过在需要特定顺序的标题组之间放置一个空行来解决问题,因为显然
clangformat
只对
#include
指令组进行排序,中间没有非
#include

固定原件。c:

struct MyStruct {
    uint8_t value;
};
#include <stdint.h>
#include <stddef.h>
#include "MyStruct.h"

int main (int argc, char **argv) {
    struct MyStruct s = { 0 };
    return s.value;
}
#include "MyStruct.h"
#include <stddef.h>
#include <stdint.h>

int main(int argc, char **argv) {
  struct MyStruct s = {0};
  return s.value;
}
#include <stdint.h>
#include <stddef.h>

#include "MyStruct.h"

int main (int argc, char **argv) {
    struct MyStruct s = { 0 };
    return s.value;
}
#include <stddef.h>
#include <stdint.h>

#include "MyStruct.h"

int main(int argc, char **argv) {
  struct MyStruct s = {0};
  return s.value;
}
#include <stdint.h>
#include <stddef.h>
// must come after stdint.h
#include "MyStruct.h"

int main (int argc, char **argv) {
    struct MyStruct s = { 0 };
    return s.value;
}

clang format在项目中重新格式化了ASM代码,因为我们有效地做到了这一点:

#define ASM _asm

ASM {

  ...

}

它不会中断工作流程

系统具有配置开关: “C_Cpp.clangg_格式”包括:false, 但它不起作用,我不知道怎么了

我的版本是:ms vscode.cpptools-0.13.1

这是我的解决方案:

对于稳定的工作流程,请使用语法:

//叮当作响

…这是你的密码


//除其他答案中描述的场景外,
-sort includes
可能会中断使用预编译头的项目。如图所示:

一旦看到第一个C标记,就不能使用预编译头

这同样适用于VisualStudio

实际上,这通常意味着预编译头文件必须是第一个包含的头文件。如果让
clangformat
为您排序,那么当预编译头不是第一个包含的文件时,您的编译很可能会中断



你可以将你的PCH文件命名为
0000000000000000\u PCH.h
,但我想我已经用这样一个荒谬的例子表明了我的观点,如果clang格式破坏了有效的代码,那将是非常无用的,你不认为吗?@EOF,同意,但你能保证clang格式没有bug吗?:)可执行文件是否相同?此外,我认为@WeatherVane的问题是关键。如果编译原始程序和重新格式化的程序,并且生成的可执行文件相同,那么您可以确信没有语义更改。虽然我个人觉得你不太可能在叮当声格式中找到这种性质的bug,但如果你在一个需要极度偏执的环境中工作,那么测试将非常简单。如果你的项目是一个只包含头文件的库,或者也包含头文件,那么检查二进制文件是不够的,您还需要良好的覆盖率测试。。。这就是为什么我们在不同级别测试我们的软件;)好主意,不过从技术上讲,你仍然需要检查重要的空格(字符串)。另一个重要的空格是终止预处理器指令的换行符。还有分隔字母数字标记的空格-
否则如果
不是
elseif
,我们假设它不会破坏这些标记。在这两种情况下,你都应该期待语法错误,而不是语义上的细微变化。@KarolyHorvath:虽然我对clang格式不熟悉,但它的作者肯定想到了字符串文字?还有
#define foo(bar)
#define foo(bar)的区别
以及许多其他问题,如插入或删除新行时的更改。我认为“仅影响空白”并不完全正确,因为它会打断长字符串,引入额外的引号
clang-format-5
还可以在名称空间结束大括号处引入注释,即
}//namespa