[英]Is there any advantage of such coding-style?
|在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))
}
它是模式的一部分。
if (!some_function(...))
return false;
if (!other_function(...))
return false;
return true;
編寫它的人決定不改變模式只是因為只有一個函數調用。 最終這是一個品味問題。
因此,代碼沒有問題。 如果有人使用任何提到的片段,至少我不會受到懲罰。
這些是我認為是原因的原因:
結論是我在開始時所說的。 只要代碼易於理解就沒關系。 關於一些優化收益,我認為這個編譯器足夠聰明,可以照顧。
基本上,不,它使用更多代碼和更多指令來說同樣的事情。
通常,這表示以下兩種情況之一:
嗯。 在這種情況下,它可能表示從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:
現在,觀察即使完全優化,它仍然不會像斷言那樣創建完全相同的代碼。
除了已經說過的內容,並且由於這是標記的編碼風格,第一個代碼包含一些可能被認為是危險的樣式。 但由於它是編碼風格,對它的看法將是主觀的。
if
沒有跟隨括號被許多程序員認為是壞的和危險的風格。 對於else, else if, for, while, do...while, switch
同樣的事情else, else if, for, while, do...while, switch
。 例如,MISRA-C禁止這兩種風格(MISRA-C:2004 14.7和14.8)。
(就我個人而言,我不同意這兩者中的前者,我認為有很多情況下多個return語句使代碼更具可讀性,特別是在發生大量錯誤檢查的函數中,例如解析器等)
我會走出困境直接說是的,后者的風格更優越。 那是:
if (!func())
return FALSE;
return TRUE;
...並假設func()已經返回一個布爾值,上面的樣式不如:
return func();
如果前者看起來更具可讀性,那么我會懇請那些這樣認為可以更好地理解表達的人。 如果論證是它更好地強調了這個函數返回TRUE或FALSE,那就意味着讀者不會知道func()
是如何工作的,這些應該被那些看到函數的人理解並試圖真正理解邏輯而不僅僅是霰彈槍調試隨機的代碼位。
也就是說,這往往會在實踐中發生,因為多個開發人員維護代碼,因為人們暫時修改代碼以使調試更容易,等等。
我不認為這樣的代碼存在是一個問題,但我會斷言簡潔的解決方案更好,因為它保證它至少與更長的一個有效或更多,這意味着額外的開銷,我們只能希望讓編譯器優化掉(我不希望所有編譯器的這種分支情況都發生這種情況,即使現在優化編譯器有多好)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.