GCC
Security
clang
coding
CERTC

CERT C入門(2) Rule 02. Declarations and Initialization (DCL)

基本事項

CERT C入門(1) Rule 01. Preprocessor (PRE)
https://qiita.com/kaizen_nagoya/items/8d2cb4158ed53d5a0a28
参照のこと。

CERT Cは、頻繁に構造が変わることがある。ここに記載したURLは、
2018年3月22日(水)現在のものだる。URLが繋がらなければ、見出しの文字で検索してください。

Rule 02. Declarations and Initialization (DCL)

https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=87152215

DCL30-C. Declare objects with appropriate storage durations

https://wiki.sei.cmu.edu/confluence/display/c/DCL30-C.+Declare+objects+with+appropriate+storage+durations

dlc30非適合例

dlc30n.c
#include <stdio.h>

const char *p;
void dont_do_this(void) {
  const char c_str[] = "This will change";
  p = c_str; /* Dangerous */
}

void innocuous(void) {
  printf("%s\n", p);
}

int main(void) {
  dont_do_this();
  innocuous();
  return 0;
}

誤り(error)も警告(warning)も出ず、そのままコンパイル・実行できる例

$./cert.sh dlc30n
clang dlc30n.c
This will change
gcc-6 dlc30n.c

$記号は入力促進記号(prompt)です。$の文字を入れる必要はありません。

LLVM/clangとgcc6とで実行結果が違う。

なお、ここで利用しているシェルスクリプトは
コンパイル用shell script
https://qiita.com/kaizen_nagoya/items/74220c0577a512c2d7da

dlc30適合例

dlc30c.c
#include <stdio.h>


void this_is_OK(void) {
  const char c_str[] = "Everything OK";
  const char *p = c_str;
  /* p is inaccessible outside the scope of string c_str */ 
  printf("%s\n", p);
}

int main(void) {
  this_is_OK();
  return 0;
}
$ ./cert.sh dlc30c
clang dlc30c.c
Everything OK
gcc-6 dlc30c.c
Everything OK

DLC30適合例2

dlc30c2.c
#include <stdio.h>

const char *p;
void is_this_OK(void) {
  const char c_str[] = "Everything OK?";
  p = c_str;
  /* ... */
  printf("%s\n", p);
  p = NULL;
}

int main(void) {
  is_this_OK();
  return 0;
}
$ ./cert.sh dlc30c2
clang dlc30c2.c
Everything OK?
gcc-6 dlc30c2.c
Everything OK?

dlc30非適合例2

dlc30n2.c
#include <stdio.h>

char *init_array(void) {
  char array[10];
  /* Initialize array */
  return array;
}

int main(void) {
  char * p = init_array();
  printf("%s\n", p);
  return 0;
}
$ ./cert.sh dlc30n2
clang dlc30n2.c
dlc30n2.c:6:10: warning: address of stack memory associated with local variable 'array' returned [-Wreturn-stack-address]
  return array;
         ^~~~~
1 warning generated.

gcc-6 dlc30n2.c
dlc30n2.c: In function 'init_array':
dlc30n2.c:6:10: warning: function returns address of local variable [-Wreturn-local-addr]
   return array;
          ^~~~~
(null)

警告はclang/llvm, gccで類似だが実行結果が違う。