13

次のコードを使用します。

int issuecode(int i)
{
  return 2 * i;
}

int main(int argc, char **argv)
{
  return issuecode(argc);
}

私が理解しているように、Cプログラムとしてコンパイルすると、未定義の動作になります。これらの標準的な引用に基づいて推論します。

C99、7.26 (または C11、7.31)

次の名前は、便宜上、個々のヘッダーの下にグループ化されています。以下で説明するすべての外部名は、プログラムによって含まれるヘッダーに関係なく予約されています。

C99、7.26.2 (または C11、7.31.2)

isまたはで始まる関数名to、および小文字を<ctype.h>ヘッダーの宣言に追加できます。

C99、7.1.3 (または C11、7.1.3)

  1. 各ヘッダーは、関連する副次節にリストされているすべての識別子を宣言または定義し、オプションで、関連する将来のライブラリ指示の副次節にリストされている識別子と、任意の使用またはファイルスコープ識別子としての使用のために常に予約されている識別子を宣言または定義します。

    [...]

    • 次の節のいずれかにある外部リンケージを持つすべての識別子 (将来のライブラリの指示を含む) は、常に外部リンケージを持つ識別子として使用するために予約されています。
  2. [...] プログラムが予約されているコンテキストで識別子を宣言または定義する場合 (7.1.4 で許可されている場合を除く)、または予約された識別子をマクロ名として定義する場合、動作は未定義です。

上記に基づいて、関数名issuecodeは実際には で使用するために予約されていると思われる<ctype.h>ため、プログラムには技術的に UB があります。

質問 0 (サニティ チェック): 標準の読み取りは正しく、プログラムの動作は技術的に未定義ですか?

質問 1: C++ コードとしてコンパイルされた場合、プログラムは UB を持ちますか?

次の引用から、C の「将来のライブラリの方向性」は C++ 標準ライブラリの一部ではないと言えますが、よくわかりません。

C++11、21.7

  1. 表 74、75、76、77、78、および 79 は、ヘッダー<cctype><cwctype><cstring><cwchar><cstdlib>(文字変換) 、および<cuchar>をそれぞれ説明しています。

  2. これらのヘッダーの内容は、標準 C ライブラリ ヘッダー<ctype.h><wctype.h><string.h><wchar.h>、および<stdlib.h>C Unicode TR ヘッダー とそれぞれ同じである必要がありますが、次の変更が加えられています。

「次の変更」のいずれも、追加の予約済み識別子について言及していません。表 74 は、isdigitおよびのような関数名の課税リストですisalnum

C++11、C.2

1. この節では、標準 C ライブラリに含まれる C++ 標準ライブラリの内容を要約します。また、他の節 (17.6.1.2、18.2、21.7) に記載されている標準 C ライブラリからの定義、宣言、または動作の明示的な変更もまとめています。

7. C++ 標準ライブラリは、表 153 に示すように、C ライブラリから 209 個の標準関数を提供します。

繰り返しますが、表 153 は課税リストです。

質問 2:質問 1 で私が間違っていて、プログラムが実際に C++ にも UB を持っていると仮定すると、次の変更はこれに影響しますか?

namespace foo {

  int issuecode(int i)
  {
    return 2 * i;
  }

}

using namespace foo;

int main(int argc, char **argv)
{
  return issuecode(argc);
}

注:標準の引用は、それぞれの言語バージョンで公開されている最新のドラフトであるドラフト N1256 (C99)、N1570 (C11)、および N3242 (C++11) から引用されています。

4

2 に答える 2

0

C++11 17.6.1.2 ヘッダー

172) C 標準ライブラリ ヘッダー (附属書 D.5) もグローバル名前空間内の名前を定義しますが、C ライブラリ機能 (17.6.1.2) の C ++ ヘッダーもグローバル名前空間内の名前を定義する場合があります。

ただし、C ++ 標準ライブラリでは、宣言 (C でマクロとして定義される名前を除く) は名前空間 std の名前空間スコープ (3.3.6) 内にあります。これらの名前が最初にグローバル名前空間スコープ内で宣言され、次に明示的な using 宣言 (7.3.3) によって名前空間 std に注入されるかどうかは指定されていません。

したがって、含まれていない場合<cctype>、動作は明確に定義されています。もしそうなら、それは不特定です。

于 2013-07-06T18:02:37.087 に答える