我要怎样用副作用的代码?
-
09-09-2019 - |
题
我工作的一个项目上的每8051字节数的位置。因此,我使用一些全局变量,我通常不会。传递指针到一个函数的正常方法这里添加了太多的开销。
我有许多使用单个位的变量函数(编译器特定扩展为 C 强>)转换成信号的函数的结果在除了正常的返回值。
bit global_error_flag = 0;
bit global_data_ready_flag = 0;
unsigned char A_Function (void) {
// Do some stuff
if ( badness ) {
global_error_flag = 0;
global_data_ready_flag = 1;
return 0;
}
if ( data_is_ready_use ) {
global_data_ready_flag = 1;
}
return a_value;
}
void Other_Function (void) {
unsigned char c;
c = A_Function();
if( global_error_flag) {
// Do error stuff here.
}
else
if( global_data_ready_flag ) {
// Do data processing here.
}
global_error_flag = 0;
global_data_ready_flag = 0;
}
由于该技术是邪恶的,是有一些办法可以使代码更清晰?
我应该如何最好的说明哪些函数调用会设置这些标志的副作用?有评论还不够吗?我应该命名功能,以表明自己的API(准匈牙利式)?我应该使用一个宏标记这样的调用:
#define FUNCTION_SETS_FLAGS(code) (code)
FUNCTION_SETS_FLAGS( c = A_Function() );
任何其他的想法?
解决方案
您全局标记为清楚起见,这是一个良好的开端。
在理想情况下你想要的东西,如果你搞错了,将无法编译。这意味着宏和意见将无法正常工作。
我会坚持到命名约定的功能 - 不一定是匈牙利人,但类似A_Function_Returns_Flags
,或者如果你能想到的,更简洁
其他提示
使用约定,不管你怎么称呼它“匈牙利”与否,是我能想到的,以纪念这个副手的最佳途径。文体上,某种命名的前缀的将是在空的#define优选的,至少对我
这其实是很常见的,我想。我知道的是,S60的编程环境,使用了大量的功能常规标签来表明他们抛出异常,例如。
我做了我的博士在Java中的一个类似的问题。我可以告诉你一件事,你不应该做的:因为你靠居然有人读它不依赖于文件。你需要在方法名称添加一些暗示表明,用户应该阅读文档,了解副作用。如果你选择的东西,都与它保持一致,你可能站在最机会。
如果你只是想提一提,一个函数影响全局变量(一个或多个),然后进行简单(匈牙利)前缀可能的帮助。
但是,如果你想提的每一个旗(县),它影响的话,使用函数头可能是要走的路。像例如,
/*************************************************************************
* FUNCTION : <function_name>
* DESCRIPTION : <function description>
* PARAMETERS :
* Param1 - <Parameter-1 explanation>
* Param2 - <Parameter-2 explanation>
* Param3 - <Parameter-3 explanation>
* RETURN : <Return value and type>
* GLOBAL VARIABLES USED:
* Global1 - <Global-1 explanation>
* Global2 - <Global-2 explanation>
* Global3 - <Global-3 explanation>
*************************************************************************/
您可以使用宏来模拟函数有更多的参数:
unsigned char _a_function(void);
#define A_Function(ret_val) (*(ret_val) = _a_function(), !global_error_flag)
...
unsigned char var;
/* call the function */
if (!A_Function(&var))
{
/* error! */
}
else
{
/* use var */
var++;
}
我还没有尝试编译它,所以不能说这将工作,但我认为它应该。
首先,我会尝试将它的方式,只有一个生产者,只有一个为每个标志的使用者代码。 然后,我将清除/只在需要时设置一个标志。 作为用于指示所述副作用,在功能上,doxygen的样式的标准头,应该足够:
// Function func
// Does something
// Consumes ready_flag and sets error_flag on error.
int func()
{
if (ready_flag)
{
//do something then clear the flag
if (some_error)
error_flag = x;
ready_flag = 0;
}
//don't mess with the flags outside of their 'scope'
return 0;
}
在另一方面,如果错误和准备标志是互斥的,可以使用一个字节(或比特的字节内/注册)以指示就绪或错误状态。
为错误,1 0未就绪/无差错和2就绪/无差错(或-1,0,1,等等)
IIRC,标准的8051指令集并不单位进行操作,因此使用全字节的(各种)标志不应该给你一个巨大的性能损失。
如果您还没有这样做的话,你可能也想看看sourceforge上的 SDCC项目,这是一个C编译器专指用于嵌入式开发也瞄准8051,除了编译器支持许多定制的,各种用例和非标准目标特定编译器内在,也是我个人发现发展团队是非常开放和回应有关新的增强功能和其他相关功能要求的想法。
如果你真的要坚持使用这些全局变量,你可以把它显然是一个功能可以通过预期作为函数的参数对它们的引用对其进行修改:
unsigned char A_Function (bit *p_error_flag, bit *p_data_ready_flag)
{
...
}