当你在写与 Marlin 相关的代码时,请遵循以下规范。提交的代码若不接近当前的代码风格,那么会被要求更改。你的代码审核人员应该指出哪里需要被更改。
缩进对于可读性与可维护性起着至关重要的作用,并且能让一些普通文本编辑器(TextMate,Sublime 等)正确地按照代码层级折叠代码。
<tab>
键,<tab>
会将你拉入无尽的深渊。#if
及其他的预处理语句应该增加它的缩进:void myFunction() { if (myCondition == 0) { #ifdef PETER_PARKER slingWeb(100); #else findPhoneBooth(); #endif } }
Marlin 使用的括号风格有以下目的:
{ (…)
倘若垂直的缩进空格让代码的可读性更强,那么增加一个空行比使用不同的括号风格更好:
if (a == 1) {
void pizza(int slices) {
“一个真正的括号风格”例子:
void my_function(void) { if (...) { ... } else { ... } switch (val) { case 1: SERIAL_CHAR('Q'); break; case 2: SERIAL_CHAR('T'); break; } }
if (…)
,while (…)
,do {…} while(…)
,switch (…)
等等。sizeof()
这种类函数就不用加括号了。val = myFunction(…);
.
和 →
操作符左右不用加空格:the_place = state→parks[echo];
。old_state = (int)state;
。myVar = aVar + bVar * cVar;
myVal = (a * b + b * c);
别在行末留空格。有些编辑器会在新行中自动增加缩进,从而你会活得拥有多余空格的行。 Git 会提示你那拥有多余空格的行,然后让你选择是否要去掉那些空格。但是一旦它帮你去掉了,之后的改动会很烦。
注释是一个良好的习惯,但是别太沉醉于注释。永远不要在注释当中解释当前代码是如何运行的:写出一眼就能看出来工作机制的代码比这种注释要好得多,而且给很烂的代码写注释是一种浪费生命的行为。
一般情况下,注释所代表的是你的代码是干嘛的,而不是你的代码是如何工作的。在函数体中的注释应尽量的少。如果一个函数非常的复杂,你应该考虑分段地把注释写在函数中每个基本单元内。将细节代码写在函数头中,用于阐述它是干嘛以及为什么它要这么干。
.h
文件中。/**
* 这是 Marlin 中的一种比较好的多行注释。
* 请坚持使用它。
*
* 这种属于类“D 型氧气”风格,一旦关键字被添加,
* 我们便能够自动生成代码文档并且提供更多
* 完整的开发指南.
*/
//
注释。// 一行或两行时 // 应该使用这样的注释。
Marlin 源代码的文件名最好使用 lowercase_with_underscores.ext
(带_下划线_的小写.扩展名)这种格式。在别的地方贡献的代码应该遵守他们组织的规定。
.cpp
后缀.c
后缀.h
后缀平面文件布局
分级文件布局
对于 Marlin 当中的变量、数据成员、函数以及方法使用 带_下划线_的小写
。对于已经使用 camelCase
驼峰命名法的就不要改动它了。Marlin 中的类使用 MyClassName
或 my_class_name
。核心的类使用驼峰法,普通的类使用下划线法。
my_function_name(int in_integer, float in_float=0.0)
MyClass
, classMethod
, classData
local_variable
, global_variable
, const_value
#define
定义的任何 MACRO_NAME
EnumeratedType
尽量使用 avr-libc 或者 Arduino 中的已捆绑的库。Marlin 中所需要编译的库应该在 package 中被引用,从而保证版本的兼容性。
Marlin 由 C/C++ 编写,并且由 Makefile
命令或最新版的 Arduino 编译。在 1.1 版本的 Marlin 中,编译可由 Arduino IDE,Teensyduino,PlatformIO,make
以及 cmake
进行。
在更新的版本中,Marlin 不再兼容先前版本(pre-2017)的工具链。能与 Marlin 1.1.x 兼容的最旧版本的 Arduino IDE 为 1.6.8。
constexpr
的值与函数float
与 constexpr
合法性的 static_assert(test,“error”)
函数uint8_t
,int32_t
,不建议使用 short
,int
,long
。double
为 float
类型,因此它们的大小都为 32 位。与 double
相比较,最好使用 float
类型,除非当前的 32 位架构对于数据精度拥有更高的需求。malloc()
,free()
,new
,delete
这种动态内存分配的函数时明令禁止的!它们对于一些 32 位的程序会产生歧义。PSTR
和 PROGMEM
宏来在内存中存放字符串。在使用宏、轻量函数等应该避免重复,例如:
#if ENABLED(FEATURE_ONE) const char blue = '1'; #else const char blue = '0'; #endif
不如:
const char blue = #if ENABLED(FEATURE_ONE) '1' #else '0' #endif ;
更不如:
const char blue = TERN(FEATURE_ONE, '1', '0');
millis()
由于比较占资源,倘若你想使用它多次,请将它放入 const millis_t var
中。Marlin.h
,当引用 MarlinConfig.h
或 MarlinConfigPre.h
程序能够正常使用时也不要引用 Marlin.h
。MarlinConfig.h
或 MarlinConfigPre.h
。#if
后引用对应需要被使用的头文件。<Arduio.h>
,<inttypes.h>
和 <u8glib.h>
。#define
代替 const
。#if
/ #endif
。#if ENABLED(FEATURE_NAME)
/ #endif
来启用对应的功能。它可以让对应功能以外部的方式被启用。if DISABLED(FEATURE_NAME)
/ #endif
来禁用对应的功能。#define
来避免重复的模板代码。#if
语句末的 #endif
后增加标签,例如:#endif // SDSUPPORT || ULTRALCD
。
在 macros.h
中,存在很多便捷的宏。