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

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: 意味のある出力が出るようにする。
 検討中。

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

利用コンパイラ

1)
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

2)
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

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.