Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C/C++の予約語と衝突する識別子を定義しているのを何とかしたい #1124

Closed
berryzplus opened this issue Dec 31, 2019 · 5 comments

Comments

@berryzplus
Copy link
Contributor

berryzplus commented Dec 31, 2019

問題内容

#1123 (review)

先頭の文字がアンダースコアで次の文字が大文字の識別子は予約語なので使ってはいけません。

コード全体を Grep してみました。

  1. m/\b_[A-Z]/ を「大文字小文字区別する」でGrep。
  2. 検索結果を s/^.*\b(_[A-Z]\w+)([^\r\n]*)/$1\r\n$2/g で全置換。(何回か繰り返し
  3. 置換結果を s/[^0-9A-Za-z_\r\n]+//g で全置換。
  4. 置換結果を s/^\r\n//g で全置換。
  5. Ctrl + A で全選択して Alt + A で選択範囲ソート。
  6. Alt + M で重複行排除して「N行をマージしました」をOKで閉じる。
検出した予約語の総数は 208 でした。

_A64
_ALT
_APP_NAME_
_APP_NAME_2_
_APP_NAME_3_
_APP_NAME_DEV_
_APS_NEXT_COMMAND_VALUE
_APS_NEXT_CONTROL_VALUE
_APS_NEXT_RESOURCE_VALUE
_APS_NEXT_SYMED_VALUE
_AddData
_AddListener
_AdjustInMonitor
_Alignas
_Alignof
_AppendSz
_Atomic
_BUFSIZE
_Begin
_Bool
_CARETMARGINRATE
_CARETMARGINRATE_CARETMARGINRATE_CARETMARGINRATE
_CLIENT_BLOCK
_CODE_SUFFIX_
_CONSOLE
_COPYWITHLINENUM
_COptWithA
_COptWoA
_CRTDBG_ALLOC_MEM_DF
_CRTDBG_LEAK_CHECK_DF
_CRTDBG_MAP_ALLOC
_CRT_SECURE_NO_WARNINGS
_CTRL
_CheckJisAnyPart
_CheckSavingCharcode
_CheckSavingEolcode
_CheckUtf16Char
_CheckUtf16Eol
_CheckUtf16EolBE
_CheckUtf16EolLE
_CmdLineOpt
_Complex
_CreateLayout
_CreateMainWindow
_CrtSetDbgFlag
_DEBUG
_DEBUG_SUFFIX_
_DEEBUG
_DL
_DT
_Data
_DecodeBase64
_DecodeMimeHeader
_DecodeQP
_DecodeUU_line
_DefaultConfig
_DispEOF
_DispEOL
_DispTab
_DispWrap
_DoGyomatsuKinsoku
_DoGyotoKinsoku
_DoKinsokuSkip
_DoKutoBurasage
_DoLayout
_DoTab
_DoWordWrap
_Doing
_DrawEOL
_DrawRulerCaret
_DrawTabArrow
_EC
_EDITL
_Empty
_EncodeBase64
_End
_EucjpToUni_char
_ExParam_Evaluate
_ExParam_SkipCond
_ExceptMRU_Counts
_ExistKinsokuHead
_ExistKinsokuKuto
_FT
_GREPEXCLUDEFILE_Counts
_GREPEXCLUDEFOLDER_Counts
_GREPFILE_Counts
_GREPFOLDER_Counts
_GSTR_APPNAME_
_Generic
_GetDocLineData
_GetDocLineDataWithEOL
_GetEOLType_uni
_GetEOLType_unibe
_GetHexChar
_GetInitializeMutex
_GetKeywordLength
_GetMemory
_GetOpenFileNameRecover
_GetOpenedWindowArrCore
_GetRawPx
_GetSizeRef
_GetTabGroupInfo
_GetWindowRectForInit
_HexToInt
_HlsTuple
_HoldBookmarks_And_AddToMRU
_I64
_INI_T
_IS_REL_PATH
_IS_SJIS_1
_IS_SJIS_2
_Imaginary
_In_
_In_opt_
_In_opt_z_
_Index
_Init
_InitBrushColor
_InitClipping
_InsertAfterPos
_InsertBeforePos
_IsFileUpdatedByOther
_IsPosKeywordHead
_JisToUni_block
_Length
_MAC
_MAX_DIR
_MAX_DRIVE
_MAX_EXT
_MAX_FNAME
_MAX_PATH
_MBCS
_MRUFOLDER_Counts
_MRU_Counts
_MSC_VER
_M_AMD64
_M_IA64
_M_IX86
_M_X64
_MakeOneLine
_MyGetFreeSystemResources32
_NORMAL_BLOCK
_NUM_TO_STR
_N_E_W_
_Noreturn
_OnLine1
_OnLine2
_Pragma
_PushBottom
_REPLACEKEY_Counts
_Recovery
_RemoveListener
_Resolve
_SEARCHKEY_Counts
_SHIFT
_SQL_RUN
_S_IFDIR
_SetDebugMode
_SetDragMode
_SetHwnd
_SetNextLayout
_SetNextLine
_SetPrevLayout
_SetPrevLine
_SetRawLength
_SetStringLength
_Size
_SjisToJis_char
_SjisToUni_char
_Static_assert
_SwapHLByte
_T
_T2
_TAG_
_TBBUTTON
_TRUNCATE
_TagJumpKeyword_Counts
_TextTemplate
_Thread_local
_ToDoChecking
_ToDoLock
_UNICODE
_USE_META_ALIAS
_UTF8ToUnicode
_UUDECODE_CHAR
_UniToEucjp_char
_UniToLatin1_char
_UniToSjis_char
_UniToUtf7SetB_block
_UniToUtf7SetD_block
_UniToUtf8_char
_UnicodeToHex
_UnicodeToUTF8
_UnicodeToUnicode_in
_UnicodeToUnicode_out
_Utf7SetBToUni_block
_Utf7SetDToUni_block
_Utf8ToUni_char
_VersionString
_WIN32
_WIN32_IE
_WIN32_WINDOWS
_WIN32_WINNT
_WIN32_WINNT_WIN2K
_WIN32_WINNT_WIN7
_WIN64
_WriteFile
_XC

4分の1くらいは「本物の予約語」なので無視して考えると、違反は 156件 でした。

こういうこと書くと、Microsoftが定義した予約語は本物じゃねーよ とか突っ込む人いそうですが、メンドクサイのでMicrosoftのコンパイラ定数も「C/C++予約語」であるものとして考えます。

C/C++予約語のルールに違反した識別子の (BLACK) リスト

_ALT
_APP_NAME_
_APP_NAME_2_
_APP_NAME_3_
_APP_NAME_DEV_
_AddData
_AddListener
_AdjustInMonitor
_AppendSz
_BUFSIZE
_Begin
_Bool
_CARETMARGINRATE
_CARETMARGINRATE_CARETMARGINRATE_CARETMARGINRATE
_CODE_SUFFIX_
_COPYWITHLINENUM
_COptWithA
_COptWoA
_CTRL
_CheckJisAnyPart
_CheckSavingCharcode
_CheckSavingEolcode
_CheckUtf16Char
_CheckUtf16Eol
_CheckUtf16EolBE
_CheckUtf16EolLE
_CmdLineOpt
_CreateLayout
_CreateMainWindow
_CrtSetDbgFlag
_DEBUG_SUFFIX_
_DEEBUG
_DL
_DT
_DecodeBase64
_DecodeMimeHeader
_DecodeQP
_DecodeUU_line
_DefaultConfig
_DispEOF
_DispEOL
_DispTab
_DispWrap
_DoGyomatsuKinsoku
_DoGyotoKinsoku
_DoKinsokuSkip
_DoKutoBurasage
_DoLayout
_DoTab
_DoWordWrap
_Doing
_DrawEOL
_DrawRulerCaret
_DrawTabArrow
_EC
_EDITL
_Empty
_EncodeBase64
_End
_EucjpToUni_char
_ExParam_Evaluate
_ExParam_SkipCond
_ExceptMRU_Counts
_ExistKinsokuHead
_ExistKinsokuKuto
_FT
_GREPEXCLUDEFILE_Counts
_GREPEXCLUDEFOLDER_Counts
_GREPFILE_Counts
_GREPFOLDER_Counts
_GSTR_APPNAME_
_GetDocLineData
_GetDocLineDataWithEOL
_GetEOLType_uni
_GetEOLType_unibe
_GetHexChar
_GetInitializeMutex
_GetKeywordLength
_GetMemory
_GetOpenFileNameRecover
_GetOpenedWindowArrCore
_GetRawPx
_GetSizeRef
_GetTabGroupInfo
_GetWindowRectForInit
_HexToInt
_HlsTuple
_HoldBookmarks_And_AddToMRU
_INI_T
_IS_REL_PATH
_IS_SJIS_1
_IS_SJIS_2
_Index
_Init
_InitBrushColor
_InitClipping
_InsertAfterPos
_InsertBeforePos
_IsFileUpdatedByOther
_IsPosKeywordHead
_JisToUni_block
_MRUFOLDER_Counts
_MRU_Counts
_MakeOneLine
_MyGetFreeSystemResources32
_NORMAL_BLOCK
_NUM_TO_STR
_OnLine1
_OnLine2
_PushBottom
_REPLACEKEY_Counts
_Recovery
_RemoveListener
_Resolve
_SEARCHKEY_Counts
_SHIFT
_SQL_RUN
_SetDebugMode
_SetDragMode
_SetHwnd
_SetNextLayout
_SetNextLine
_SetPrevLayout
_SetPrevLine
_SetRawLength
_SetStringLength
_Size
_SjisToJis_char
_SjisToUni_char
_Static_assert
_SwapHLByte
_T2
_TagJumpKeyword_Counts
_TextTemplate
_Thread_local
_ToDoChecking
_ToDoLock
_USE_META_ALIAS
_UTF8ToUnicode
_UUDECODE_CHAR
_UniToEucjp_char
_UniToLatin1_char
_UniToSjis_char
_UniToUtf7SetB_block
_UniToUtf7SetD_block
_UniToUtf8_char
_UnicodeToHex
_UnicodeToUTF8
_UnicodeToUnicode_in
_UnicodeToUnicode_out
_Utf7SetBToUni_block
_Utf7SetDToUni_block
_Utf8ToUni_char
_VersionString
_WriteFile
_XC

数が多いのと、この辺の定義し直しても具体的な新機能には結びつかないのとで、当面は放置しておくつもりでいます。

githashのバージョン定義定数が引っかかっていて、あのへんの定数は Appveyor & Azure Pipelines の両対応のために再定義する話があった気がするので、その時にまた会話する感じになるのかな、と思っています。

再現手順

アプリ挙動に影響しない部分なので再現手順はありません。
ソースコードの書きっぷりの不備なのでアプリ機能に影響はありません。

再現頻度

ある意味「常に発生」しています。
実害はないので「発生してない」とも言えます。

問題のカテゴリ

  • その他の問題

環境情報

ソースコードの問題なので関係ありません。

スクリーンショット

@berryzplus
Copy link
Contributor Author

ふと思ったけど、こういうのも本来ダメなんだよね。

  // テンプレートクラス内の宣言
  using _Myt = std::basic_string<_Elem>;
  _Myt& operator = (const _Myt&) = delete;\

MSVCのテンプレートクラスの記述は、ほぼほぼこんな感じ。
これは開発環境の一部として適用するインフラクラスだからそうなのか、
MSのライブラリメンテナがやらかしてんのか微妙な気がします。

普通に考えたら「前者一択」なんだけど、マイクロソフトだからなぁ・・・。

@k-takata
Copy link
Member

k-takata commented Jan 2, 2020

https://ja.cppreference.com/w/cpp/language/identifiers

ここでいう「予約されています」は、標準ライブラリヘッダが内部使用のためにそのような識別子を #define または宣言するかもしれない、コンパイラがそのような種類の非標準の識別子を事前定義するかもしれない、および名前マングリングアルゴリズムがそのような識別子が使用されていないことを仮定しているかもしれない、という意味です。 プログラマがそのような識別子を使用した場合、動作は未定義です。

ということで、標準ヘッダがまさにそういう使い方をするために予約されているので問題ないですね。

@beru
Copy link
Contributor

beru commented Jan 2, 2020

コンパイラ付属の標準ライブラリ実装側はユーザー側のコード(おそらくグローバル識別子)と衝突しないように予約語のルールに則ったコードを書いて実装する必要があるという事でしょうね。言語仕様で決まっているライブラリを実装するコード側では、使える識別子に関してはユーザー側とは逆の一定のルールに則る必要があるのかもしれません。主にグローバルスコープの識別子にだと思いますが。。ヘッダファイル側の記述に関しては #include でプリプロセッサで取り込まれるのと、リンク時にはシンボル名の衝突が発生しないように気を使う必要があるんでしょうね。

@berryzplus
Copy link
Contributor Author

テンプレートクラスの書き方は標準ライブラリみて覚えたので、
こういう風に書くもんだと思いこんでおりました...orz

理屈的に、gccでもそういう書き方がなされていたとしても「真似しちゃダメよ」ってことなんですね。う~む、気を付けよう。

@berryzplus
Copy link
Contributor Author

モチベーションが尽きたので閉じてしまいます。 #1394

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants