簡體   English   中英

為什么gcc不能一致地編譯這段代碼?

[英]Why is gcc not compiling this code consistently?

我正在為我正在參加的C編程課程做實驗工作。 我在我的本地Cygwin目錄中編寫了代碼,用gcc編譯它, gcc的可執行文件完全按照我想要的方式工作而沒有任何錯誤。

當我將代碼復制到學校的UNIX服務器並使用gcc編譯時,我沒有收到任何錯誤,但是當我嘗試運行它時,沒有任何反應。

我嘗試做gcc 2darray.c -Wall -pedantic ,這是返回的內容:

2darray.c: In function 'main':
2darray.c:5:3: warning: missing braces around initializer [-Wmissing-braces]
2darray.c:5:3: warning: (near initialization for 'M[0]') [-Wmissing-braces]
2darray.c:5:24: warning: C++ style comments are not allowed in ISO C90 [enabled by default]
2darray.c:5:24: warning: (this will be reported only once per input file) [enabled by default]

這些錯誤提到了有關初始化數組M一些內容,但我沒有看到我初始化它的方式有任何問題。 這是我正在嘗試編譯的代碼:

#include <stdio.h>

int main(void)
{
  int M[10][10] = {0}; // creating a 10x10 array and initializing it to 0
  int i, j; // loop variables
  int sum[10] = {0}; // creating an array to hold the sums of each column of 2d array M

  for (i = 1; i < 10; i++) // assigning values to array M as specified in directions
    {
      for (j = i - 1; j < i; j++)
        {
          M[i][j] = -i;
          M[i][j+1] = i;
          M[i][j+2] = -i;
        }
    }

  for (i = 0; i < 10; i++) // printing array M
    {
      for(j = 0; j < 10; j++)
        {
          printf("%3d", M[i][j]);
        }
      printf("\n");
    }

  printf("\n");
  for (i = 0; i < 10; i++) // calculating sum of each column
    {
      for (j = 0; j < 10; j++)
        {
          sum[i] = M[j][i] + sum[i];
        }
      printf("%3d", sum[i]);  // printing array sum
    }

  return 0;
}

我嘗試在變量聲明和第一個for循環和打印的語句之間插入一個printf語句,所以我的循環中可能出現問題?

如果相關,這是我的Cygwin目錄中輸出的內容以及我學校UNIX目錄中的內容:

  0  0  0  0  0  0  0  0  0  0
 -1  1 -1  0  0  0  0  0  0  0
  0 -2  2 -2  0  0  0  0  0  0
  0  0 -3  3 -3  0  0  0  0  0
  0  0  0 -4  4 -4  0  0  0  0
  0  0  0  0 -5  5 -5  0  0  0
  0  0  0  0  0 -6  6 -6  0  0
  0  0  0  0  0  0 -7  7 -7  0
  0  0  0  0  0  0  0 -8  8 -8
  0  0  0  0  0  0  0  0 -9  9

 -1 -1 -2 -3 -4 -5 -6 -7 -8  1

您正在訪問其邊界外的數組M的行,從而導致未定義的行為。

for (i = 1; i < 10; i++) 
// i ranges from 1 to 9
  {
    for (j = i - 1; j < i; j++)
    // j ranges from i-1 (0 when i==1) to i-1 (8 when i==9)
    // Consider what happens when j==8
      {
        M[i][j] = -i;       // j == 8
        M[i][j+1] = i;      // j == 9
        M[i][j+2] = -i;     // j == 10, out of bounds
      }
  }

當我查看你的代碼時, j+2索引讓我覺得最有可能進行越界訪問。 我復制了你的程序並添加了一行:

      M[i][j] = -i;
      M[i][j+1] = i;
      if (j+2 >= 10) puts("OUT OF RANGE");
      M[i][j+2] = -i;

當我運行該程序時,它打印了OUT OF RANGE

至於你從gcc -Wall -pedantic獲得的警告,它們並不是真正的問題。 使用-std=c99進行編譯可以避免有關//注釋的警告。 “缺失的大括號”警告是虛假的。 嵌套數據結構的初始值設定項中的嵌套大括號是可選的, {0}是將整個數據結構(數組,結構,並集)初始化為零的完全有效的慣用法。 最新版本的gcc(特別是5.2.0)沒有對此發出警告。

clang和gcc的最新版本附帶了一個可以輕視這些問題的工具。 請始終使用它,它將為您節省大量時間尋找錯誤。

$ gcc s.c -Wall -Wextra -fsanitize=undefined
$ ./a.out
s.c:15:15: runtime error: index 10 out of bounds for type 'int [10]'
s.c:15:21: runtime error: store to address 0x7fff6c53f2c0 with insufficient space for an object of type 'int'
0x7fff6c53f2c0: note: pointer points here
 09 00 00 00  e5 ef 74 8a 11 7f 00 00  08 00 00 00 09 00 00 00  b0 10 40 00 00 00 00 00  00 00 00 00
              ^

顯然,cygwin可能還不支持libubsan,所以你可能需要-fsanitize-undefined-trap-on-error ,它用一個簡單的陷阱取代了很好的錯誤信息,你可以用gdb進行調查。 是的,調試器是另一種工具,需要一點時間來學習,但不是那么多,它將為您節省更多時間來查找錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM