LoginSignup
3
1

C Secure Coding Rules(13) 5.43 Using identifiers that are reserved for the implementation [resident]

Last updated at Posted at 2018-04-06

ISO/IEC TS 17961:2013
Information Technology — Programming languages, their environments and system software interfaces — C Secure Coding Rules
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1624.pdf

n1624は、ISO/IEC JTC1 SC22 WG14の作業文書(Working Draft)です。
公式のISO/IEC TS 17961:2013原本ではありません。

ISO/IEC JTC1 SC22 WG14では、可能な限り作業文書を公開し、幅広い意見を求めています。技術内容を検討し、ISO/IEC JTC1 SC22 WG14にフィードバックするために用います。

ISO/IEC TS 17961:2013 C Secure Coding Rules(1)一覧

ISO/IEC TS 17961:2013 C Secure Coding Rules(1) All list(to be confirmed) - kaizen_nagoya @ Qiita
https://qiita.com/kaizen_nagoya/items/54e056195c4f11b850a1

一つの規則で複数回のコンパイルが必要な場合、別記事にしています。

例と作り込んだ部分と資料の断片とを一つのファイルとしている。
作り込んだところは///を記載するように変更中である。

作業予定

規則に記載のある例(断片等)をコンパイル、実行する予定です。
1: コンパイルエラーが出ないようにする。
 一accfree.cがこの段階です。
2: 実行時エラーが出ないようにする。
 ptrcomp.cがこの段階です。
3: 意味のある出力が出るようにする。
 検討中。

現状では、変な代入、奇異な操作が頻出します。コンパイルエラーが出ないようにするなるべく短い記述で済まそうという趣旨で、他意はありません。
意味のある出力があるよりよい記述に変更する予定です。

利用コンパイラ

Apple LLVM version 9.1.0 (clang-902.0.39.1)
Target: x86_64-apple-darwin17.4.0
または
clang version 6.0.0 (tags/RELEASE_600/final)
Target: x86_64-apple-darwin17.4.0

gcc-7 (Homebrew GCC 7.3.0_1) 7.3.0
Copyright (C) 2017 Free Software Foundation, Inc.

環境(Environment)

hosted Environment macOS 10.13.3 or 10.12.9

コンパイル用shell script

C版(clangとgcc)とC++版(clang++とg++)
https://qiita.com/kaizen_nagoya/items/74220c0577a512c2d7da

5.43 Using identifiers that are reserved for the implementation [resident]

EXAMPLE 1,2,3,4,7

EXAMPLE 1 In this noncompliant example, a diagnostic is required because the reserved identifier errno is redefined.
EXAMPLE 2 In this noncompliant example, a diagnostic is required because the identifier MY_HEADER_H defined in the header guard is reserved because it begins with an underscore and an uppercase letter.
EXAMPLE 3 In this compliant example, a diagnostic is not required because the identifier MY_HEADER_H defined in the header guard is not reserved.

EXAMPLE 4 In this noncompliant example, a diagnostic is required because the file scope identifiers _max_limit and _limit are reserved because they begin with an underscore.
static const unsigned int _max_limit = 1024; // diagnostic requiredEXAMPLE 7 In this compliant example, a diagnostic is not required because the identifiers BUFSIZE and MY_INTFAST16_UPPER_LIMIT are not reserved.

_my_header.h
// ISO/IEC JTC 1/SC 22/WG 14 N 1624 Date: 2012-06-26 ISO/IEC TS 17961, p.61
// http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1624.pdf
/// lines are added by Dr. Kiyoshi Ogawa, 2018
/// Compiled on 
///  Clang(LLVM) clang version 6.0.0 (tags/RELEASE_600/final) 
///  GCC(GNU) gcc-7 (Homebrew GCC 7.3.0_1) 7.3.0
/// hosted Environment macOS 10.13.3 or 10.12.9
//EXAMPLE 1 In this noncompliant example, a diagnostic is required because the reserved identifier errno is redefined.

extern int errno; // diagnostic required

//EXAMPLE 2 In this noncompliant example, a diagnostic is required because the identifier _MY_HEADER_H_ defined in the header guard is reserved because it begins with an underscore and an uppercase letter.

#ifndef _MY_HEADER_H_
#define _MY_HEADER_H_ // diagnostic required

/* contents of <my_header.h> */
#endif /* _MY_HEADER_H_ */
my_header.h
// ISO/IEC JTC 1/SC 22/WG 14 N 1624 Date: 2012-06-26 ISO/IEC TS 17961, p.61
// http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1624.pdf
/// lines are added by Dr. Kiyoshi Ogawa, 2018
/// Compiled on 
///  Clang(LLVM) clang version 6.0.0 (tags/RELEASE_600/final) 
///  GCC(GNU) gcc-7 (Homebrew GCC 7.3.0_1) 7.3.0
/// hosted Environment macOS 10.13.3 or 10.12.9
//EXAMPLE 3 In this compliant example, a diagnostic is not required because the identifier MY_HEADER_H defined in the header guard is not reserved.

#ifndef MY_HEADER_H
#define MY_HEADER_H
/* contents of <my_header.h> */
#endif /* MY_HEADER_H */
resident.c
// ISO/IEC JTC 1/SC 22/WG 14 N 1624 Date: 2012-06-26 ISO/IEC TS 17961, p.61
// http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1624.pdf
/// lines are added by Dr. Kiyoshi Ogawa, 2018
/// Compiled on 
///  Clang(LLVM) clang version 6.0.0 (tags/RELEASE_600/final) 
///  GCC(GNU) gcc-7 (Homebrew GCC 7.3.0_1) 7.3.0
/// hosted Environment macOS 10.13.3 or 10.12.9
//EXAMPLE 4 In this noncompliant example, a diagnostic is required because the file scope identifiers _max_limit and _limit are reserved because they begin with an underscore.
static const unsigned int _max_limit = 1024; // diagnostic required

#include <stdio.h> /// for printf
#include <stdlib.h> /// for EXIT_SUCCESS
#include <errno.h> /// for errno
#include <limits.h> /// for 'ULONG_MAX'
#include "my_header.h"

unsigned int _limit = 100; // diagnostic required
unsigned int getValue(unsigned int count) {
  return count < _limit ? count : _limit;
}

//EXAMPLE 7 In this compliant example, a diagnostic is not required because the identifiers BUFSIZE and MY_INTFAST16_UPPER_LIMIT are not reserved.

#include <stdio.h> /// for printf
#include <stdlib.h> /// for EXIT_SUCCESS
#include <errno.h> /// for errno
#include <limits.h> /// for 'ULONG_MAX'
#include <stdint.h> /// for SIZE_MAX
#include <inttypes.h> /// for   SIZE_MAX

static const int_fast16_t MY_INTFAST16_UPPER_LIMIT = 12000;

void print_fast16(int_fast16_t val) {
  enum { BUFSIZE = 80 };
  char buf[BUFSIZE];
  if (MY_INTFAST16_UPPER_LIMIT < val) {
    sprintf(buf, "The value is too large");
  } else {
    char fmt[BUFSIZE];
    snprintf(fmt, BUFSIZE, "%s %s", "The Value is %", PRIdFAST16);
    snprintf(buf, BUFSIZE, fmt, val);
  }
  fprintf(stdout, "\t%s\n", buf);
}

int main(void) {///
  unsigned int count=1;///
  int_fast16_t val=2;///
  printf("%d \n"",getValue(count));///
  print_fast16(val);///
  return EXIT_SUCCESS;///
}///
shell
$ ./cgl.sh resident
$ clang resident.c
1 
	The Value is  2

$ gcc-7 resident.c
1 
	The Value is  2

Example 5, 6

EXAMPLE 5 In this compliant example, a diagnostic is not required because the file scope identifiers max_limit and limit are not reserved because they do not begin with an underscore.
EXAMPLE 6 In this noncompliant example, a diagnostic is required if header is included because the identifier SIZE_MAX is reserved and the identifier INTFAST16_LIMIT_MAX is reserved because it begins with INT and ends with

resident2.c
// ISO/IEC JTC 1/SC 22/WG 14 N 1624 Date: 2012-06-26 ISO/IEC TS 17961, p.61
// http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1624.pdf
/// lines are added by Dr. Kiyoshi Ogawa, 2018
/// Compiled on 
///  Clang(LLVM) clang version 6.0.0 (tags/RELEASE_600/final) 
///  GCC(GNU) gcc-7 (Homebrew GCC 7.3.0_1) 7.3.0
/// hosted Environment macOS 10.13.3 or 10.12.9
//EXAMPLE 5 In this compliant example, a diagnostic is not required because the file scope identifiers max_limit and limit are not reserved because they do not begin with an underscore.

#include <stdio.h> /// for printf
#include <stdlib.h> /// for EXIT_SUCCESS
#include <errno.h> /// for errno
#include <limits.h> /// for 'ULONG_MAX'
#include <stdint.h> /// for SIZE_MAX
#include <inttypes.h> /// for   SIZE_MAX
#include "_my_header.h"

static const unsigned int max_limit = 1024;
unsigned int limit = 100;
unsigned int getValue(unsigned int count){
return count < limit ? count : limit;
}

//EXAMPLE 6 In this noncompliant example, a diagnostic is required if header <stdint.h> is included because the identifier SIZE_MAX is reserved and the identifier INTFAST16_LIMIT_MAX is reserved because it begins with INT and ends with _MAX.

#undef SIZE_MAX

#define BUFSIZE 80
static const int_fast16_t INTFAST16_LIMIT_MAX = 12000; // diagnostic required
void print_fast16(int_fast16_t val) {
  enum { SIZE_MAX = 80 }; // diagnostic required
  char buf[BUFSIZE];
  if (INTFAST16_LIMIT_MAX < val) {
    sprintf(buf, "The value is too large");
  } else {
    char fmt[BUFSIZE];
    snprintf(fmt, BUFSIZE, "%s %s", "The Value is %", PRIdFAST16);
    snprintf(buf, BUFSIZE, fmt, val);
  }
  fprintf(stdout, "\t%s\n", buf);
}

int main(void) {///
  unsigned int count=2;///
  int_fast16_t val=3;///
  printf("%d \n", getValue(count));///
  print_fast16(val);///
  return EXIT_SUCCESS;///
}///
shell
$  ./cgl.sh resident2
$ clang resident2.c
2 
	The Value is  3

$ gcc-7 resident2.c
2 
	The Value is  3

EXAMPLE 8

In this noncompliant example, a diagnostic is required because the identifiers for the C Standard Library functions malloc and free are reserved.

resident3.c
// ISO/IEC JTC 1/SC 22/WG 14 N 1624 Date: 2012-06-26 ISO/IEC TS 17961, p.61
// http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1624.pdf
/// lines are added by Dr. Kiyoshi Ogawa, 2018
/// Compiled on 
///  Clang(LLVM) clang version 6.0.0 (tags/RELEASE_600/final) 
///  GCC(GNU) gcc-7 (Homebrew GCC 7.3.0_1) 7.3.0
/// hosted Environment macOS 10.13.3 or 10.12.9
#include <stdio.h> /// for printf
#include <stdlib.h> /// for EXIT_SUCCESS

//EXAMPLE 8 In this noncompliant example, a diagnostic is required because the identifiers for the C Standard Library functions malloc and free are reserved.

void *malloc(size_t nbytes) { // diagnostic required
  void *ptr;
  /* ... */
  printf("malloc\n");
  /* allocate storage from own pool and set ptr */
  return ptr;
}

void free(void *ptr) { // diagnostic required
  /* ... */
  printf("free\n");
  /* return storage to own pool */
}

int main(void) {///
  size_t nbytes = sizeof(int);
  void * ptr = malloc(nbytes);
  free(ptr);
  return EXIT_SUCCESS;///
}///
shell
$ c./cgl.sh resident3
$ clang resident3.c
malloc
free

$ gcc-7 resident3.c
malloc
free

EXAMPLE 9

In this compliant example, a diagnostic is not required because the reserved identifiers malloc and free are not used to define functions.

resident4.c
// ISO/IEC JTC 1/SC 22/WG 14 N 1624 Date: 2012-06-26 ISO/IEC TS 17961, p.63
// http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1624.pdf
/// lines are added by Dr. Kiyoshi Ogawa, 2018
/// Compiled on 
///  Clang(LLVM) clang version 6.0.0 (tags/RELEASE_600/final) 
///  GCC(GNU) gcc-7 (Homebrew GCC 7.3.0_1) 7.3.0
/// hosted Environment macOS 10.13.3 or 10.12.9

#include <stdio.h> /// for printf
#include <stdlib.h> /// for EXIT_SUCCESS

//EXAMPLE 9 In this compliant example, a diagnostic is not required because the reserved identifiers malloc and free are not used to define functions.

void *my_malloc(size_t nbytes) {
  void *ptr;
  /* ... */
  printf("my_malloc\n");
  /* allocate storage from own pool and set ptr */
  return ptr;
}

void my_free(void *ptr) {
  /* ... */
  printf("my_free\n");
  /* return storage to own pool */
}

int main(void) {///
  size_t nbytes = sizeof(int);
  void * ptr = my_malloc(nbytes);
  my_free(ptr);
  return EXIT_SUCCESS;///
}///
shell
$ ./cgl.sh resident4
$ clang resident4.c
my_malloc
my_free

$ gcc-7 resident4.c
my_malloc
my_free

参考文献

コンパイル用shell script C版(clangとgcc)とC++版(clang++とg++)
https://qiita.com/kaizen_nagoya/items/74220c0577a512c2d7da

C言語(C++)に対する誤解、曲解、無理解、爽快。
https://qiita.com/kaizen_nagoya/items/3f3992c9722c1cee2e3a

MISRA C まとめ #include
https://qiita.com/kaizen_nagoya/items/f1a79a7cbd281607c7c9

どうやって MISRA C Example Suiteをコンパイルするか
https://qiita.com/kaizen_nagoya/items/fbdbff5ff696e2ca7f00

[C][C++]の国際規格案の例題をコンパイルするときの課題7つ。
https://qiita.com/kaizen_nagoya/items/5f4b155030259497c4de

文書履歴

ver. 0.10 初稿 20180405
ver. 0.11 gcc-7追記 Example節項目追記 20180408
ver. 0.12 ありがとう追記 20230413

最後までおよみいただきありがとうございました。

いいね 💚、フォローをお願いします。

Thank you very much for reading to the last sentence.

Please press the like icon 💚 and follow me for your happy life.

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1