2012-06-23 78 views
4

我有一點被投擲此警告的示例代碼:這是C中的未定義行爲? (C = X)+(C == y)的

main.c: In function ‘getline_’: 
main.c:30:32: warning: operation on ‘c’ may be undefined [-Wsequence-point] 

在此特定練習我是避免使用||&&操作者,但這似乎不會產生未定義的行爲。編譯器消息只是一個警告,但我想知道知道的緣故。這段代碼是否會產生未定義的行爲?

24 int getline_(char s[], int limit) 
25 { 
26  int i, c; 
27  i=0; 
28  for(i=0; (i<limit-1) + ((c=getchar())!='\n') + (c!=EOF) == 3; i++){ 
29   s[i]=c; 
30  } 
31  if(c == '\n'){ 
32   s[i]=c; 
33   i++; 
34  } 
35  s[i]='\0'; 
36  return i; 
37 } 

它似乎在我的基本測試中工作正常。

編輯:根據評論更新標題,謝謝pst。

+3

僅僅因爲「它在這裏工作」並不意味着它是* defined *行爲。 * UB *可能是你一直觀察到的行爲......(它可能涉及到其他地方的倉鼠) – 2012-06-23 19:06:35

+1

這正是我想知道的原因,並且來到了這裏。 :) –

+1

考慮提取測試用例(警告可以用少得多的方式生成)並將其合併到標題中。它基本上歸結爲:'(c = x)+(c == y)' – 2012-06-23 19:08:17

回答

13

這是不確定的行爲:

(i<limit-1) + ((c=getchar())!='\n') + (c!=EOF) == 3

序列點之間的表達式的計算順序是不確定的C.它是不確定的,如果分配給cEOF平等檢查之前發生。

除了未指定的行爲,它也是未定義的行爲,因爲它違反的序列點的規則和特別這一個:

(C99,6.5p2)「。此外,前一個值是隻讀以確定要存儲的值。「

+2

迂腐的挑剔:但警告說它的未定義的行爲不規範的行爲,所以... –

+0

注意自我,需要一點lisp。感謝您指出了這一點!只是等待計時器消失接受... –

+1

@Als看到我的編輯我認爲這也是UB – ouah