|在gestremer matroska demux插件中有这个功能:
gboolean
gst_matroska_demux_plugin_init (GstPlugin * plugin)
{
/* parser helper separate debug */
GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
0, "EBML stream helper class");
/* create an elementfactory for the matroska_demux element */
if (!gst_element_register (plugin, "matroskademux",
GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))
return FALSE;
return TRUE;
}
现在gst_element_register()
是
gboolean gst_element_register (GstPlugin *plugin,
const gchar *name,
guint rank,
GType type);
Returns :
TRUE, if the registering succeeded, FALSE on error
那为什么不用以下方式写呢?
gboolean
gst_matroska_demux_plugin_init (GstPlugin * plugin)
{
/* parser helper separate debug */
GST_DEBUG_CATEGORY_INIT (ebmlread_debug, "ebmlread",
0, "EBML stream helper class");
/* create an elementfactory for the matroska_demux element */
return gst_element_register (plugin, "matroskademux",
GST_RANK_PRIMARY, GST_TYPE_MATROSKA_DEMUX))
}
答案 0 :(得分:7)
这是模式的一部分。
if (!some_function(...))
return false;
if (!other_function(...))
return false;
return true;
无论是谁编写它都决定不改变模式只是因为只有一个函数调用。最终这是一个品味问题。
答案 1 :(得分:4)
因此代码没有问题。如果有人使用上述任何一个片段,至少我不会受到惩罚。
这些是我认为原因的原因:
结论是我在开始时所说的。只要代码易于理解就没关系。关于一些优化收益,我认为这个编译器足够聪明,可以照顾。
答案 2 :(得分:3)
基本上,不是:它使用更多代码和更多指令来说同样的事情。
通常,这表示两件事之一:
嗯。在这种情况下,它可能表示从Fortran机械翻译的代码。
再次更新
好的,所以这仍然存在争议。这是一个实际的例子。观察该示例与OP示例完全同构:
C代码:
int retcod1() { return 0; }
int ex1(){
if(retcod1())
return 0;
else
return 1;
}
int ex2() {
return retcod1();
}
生成的程序集:
这是使用gcc -S -O0
生成的代码:
.file "code.c"
.text
.globl retcod1
.type retcod1, @function
retcod1:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
movq %rsp, %rbp
.cfi_offset 6, -16
.cfi_def_cfa_register 6
movl $0, %eax
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size retcod1, .-retcod1
.globl ex1
.type ex1, @function
ex1:
.LFB1:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
movq %rsp, %rbp
.cfi_offset 6, -16
.cfi_def_cfa_register 6
movl $0, %eax
call retcod1
testl %eax, %eax
je .L3
movl $0, %eax
jmp .L4
.L3:
movl $1, %eax
.L4:
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE1:
.size ex1, .-ex1
.globl ex2
.type ex2, @function
ex2:
.LFB2:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
movq %rsp, %rbp
.cfi_offset 6, -16
.cfi_def_cfa_register 6
movl $0, %eax
call retcod1
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE2:
.size ex2, .-ex2
.ident "GCC: (SUSE Linux) 4.5.1 20101208 [gcc-4_5-branch revision 167585]"
.section .comment.SUSE.OPTs,"MS",@progbits,1
.string "ospwg"
.section .note.GNU-stack,"",@progbits
为方便起见(假设SO可以处理格式)我已经为两个例程生成了代码并将它们并排放置。注意第二个例子显着更短。
.globl ex1 .globl ex2
.type ex1, @function .type ex2, @function
ex1: ex2:
.LFB1: .LFB2:
.cfi_startproc .cfi_startproc
pushq %rbp pushq %rbp
.cfi_def_cfa_offset 16 .cfi_def_cfa_offset 16
movq %rsp, %rbp movq %rsp, %rbp
.cfi_offset 6, -16 .cfi_offset 6, -16
.cfi_def_cfa_register 6 .cfi_def_cfa_register 6
movl $0, %eax movl $0, %eax
call retcod1 call retcod1
testl %eax, %eax leave
je .L3 .cfi_def_cfa 7, 8
movl $0, %eax ret
jmp .L4 .cfi_endproc
.L3: .LFE2:
movl $1, %eax
.L4:
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE1:
.size ex1, .-ex1
以下是默认优化的示例,即gcc -S
:
ex1: ex2:
.LFB1: .LFB2:
.cfi_startproc .cfi_startproc
pushq %rbp pushq %rbp
.cfi_def_cfa_offset 16 .cfi_def_cfa_offset 16
movq %rsp, %rbp movq %rsp, %rbp
.cfi_offset 6, -16 .cfi_offset 6, -16
.cfi_def_cfa_register 6 .cfi_def_cfa_register 6
movl $0, %eax movl $0, %eax
call retcod1 call retcod1
testl %eax, %eax leave
je .L3 .cfi_def_cfa 7, 8
movl $0, %eax ret
jmp .L4 .cfi_endproc
.L3: .LFE2:
movl $1, %eax .size ex2, .-ex2
.L4:
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE1:
.size ex1, .-ex1
.globl ex2
.type ex2, @function
再次,仍然明显缩短。
最后,这是一个例子,这次是完整的优化:
.globl ex1 .globl ex2
.type ex1, @function .type ex2, @function
ex1: ex2:
.LFB1: .LFB2:
.cfi_startproc .cfi_startproc
movl $1, %eax xorl %eax, %eax
ret ret
.cfi_endproc .cfi_endproc
.LFE1: .LFE2:
现在,请注意即使完全优化,仍然也不会像声明的那样创建完全相同的代码。
答案 3 :(得分:1)
除了已经说过的内容之外,由于这是标记的编码风格,因此第一个代码包含一些可能被视为危险的样式。但由于它是编码风格,对它的看法将是主观的。
if
被许多程序员认为是坏的和危险的风格。 else, else if, for, while, do...while, switch
。例如,MISRA-C禁止这两种风格(MISRA-C:2004 14.7和14.8)。
(就我个人而言,我不同意这两者中的前者,我认为在很多情况下,多个return语句使代码更具可读性,特别是在发生大量错误检查的函数中,例如解析器等。 )
答案 4 :(得分:1)
我会走出困境直接说是的,后者的风格更优越。那就是:
if (!func())
return FALSE;
return TRUE;
...假设func()已经返回一个布尔值,上面的样式不如:
return func();
如果前者看起来更具可读性,那么我会恳求那些这样认为可以更好地理解表达的人。如果论证是它更好地强调了这个函数返回TRUE或FALSE,那就意味着读者不会知道func()
是如何工作的,那些看这个函数并试图真正理解逻辑的人应该理解只是用猎枪调试随机的代码。
也就是说,这往往会在实践中发生,因为多个开发人员维护代码,因为人们会暂时修改代码以使调试更容易,等等。
我不认为这样的代码存在是一个问题,但我会断言简洁的解决方案更好,因为它保证它至少与更长的一个有效或更多,这意味着我们的额外开销只能希望编译器能够优化掉(我不希望所有编译器的这些分支情况都会发生,即使现在优化编译器有多好)。