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

#include <locale.h> 追加 #694

Merged
merged 1 commit into from
Dec 11, 2018
Merged

#include <locale.h> 追加 #694

merged 1 commit into from
Dec 11, 2018

Conversation

beru
Copy link
Contributor

@beru beru commented Dec 11, 2018

Visual Studio 2019 Preview で Debug Win32 でビルドするとエラーになるので追加しました。
今まで無くても何で大丈夫だったのかは良く分かりません。どこかの標準ヘッダーで include してるんでしょうか。。

@berryzplus
Copy link
Contributor

vs2019 の導入はまだ先だと思ってました。
これはこれでやってもいいと思います。

vc++の場合特に、ヘッダーには #pragma once が付くので
多めにインクルードしてしまったとしても影響ないと思うからです。
必要なヘッダーをインクルードしてなかった、という問題なので、対処すべきと思います。

インクルードするファイルは、
locale でいいように思いますが、ダメなんですかね?

@beru
Copy link
Contributor Author

beru commented Dec 11, 2018

インクルードするファイルは、
locale でいいように思いますが、ダメなんですかね?

#include <clocale>

がいいという事でしょうか?どちらでも良いと思います。

@beru
Copy link
Contributor Author

beru commented Dec 11, 2018

Visual Studio 2017 で /showIncludes で確認したところ

StdAfx.h
 string
  istream
   ostream
    ios
     xlocnum
      streambuf
       xiosbase
        xlocale
         xlocinfo
          xlocinfo.h
           locale.h

というように locale.h が取り込まれてました。

標準ライブラリのパスが
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023
以下になってますが、新しい開発環境のバージョンでは標準ライブラリの実装が変わって問題が出たという事のようです。

MinGWでビルドした場合でもどこかで勝手に #include していて問題が起きてなかったぽいですね。そちらはどこで #include されていたのかを調べる気は無いです。。

@berryzplus
Copy link
Contributor

インクルードするファイルは、
locale でいいように思いますが、ダメなんですかね?

#include <clocale>

がいいという事でしょうか?どちらでも良いと思います。

いいえ、です。
locale.h は C 言語向けのランタイムヘッダです。
clocale は c++ でロケール関数を使うためのランタイムヘッダです。

ぼくが言ってるのは locale という c++向けの標準ライブラリヘッダに変えなくていいかってことです。

#include <locale>

厳格な仕様では clocale は std 名前空間の中に locale.h を展開するっぽいです。
locale.h が必要になったんじゃなくて、vs2019が仕様準拠度を高めたために
グローバル ::setlocale を認識しなくなったということなのかも知れんです。
ちゃんと検証してませんが、 setlocale とか std::locale なら通るのかも、とも思うわけです。

@berryzplus
Copy link
Contributor

・・・なんか外れたこと書いてる気がします。
たぶん、こういう変更があったんじゃないかと思ってます。

No vs ver インクルード方向 説明
1 vs2017以前 clocale ⇒ locale.h locale.h の内容を std 名前空間に展開する
2 vs2019 locale.h ⇒ clocale clocale(std名前空間) を using する

詳しいことは c++er の人にお任せするとして、ざっくりとそんな印象を受けてます。

@beru
Copy link
Contributor Author

beru commented Dec 11, 2018

いいえ、です。
locale.h は C 言語向けのランタイムヘッダです。
clocale は c++ でロケール関数を使うためのランタイムヘッダです。

ぼくが言ってるのは locale という c++向けの標準ライブラリヘッダに変えなくていいかってことです。

#include <locale>

厳格な仕様では clocale は std 名前空間の中に locale.h を展開するっぽいです。
locale.h が必要になったんじゃなくて、vs2019が仕様準拠度を高めたために
グローバル ::setlocale を認識しなくなったということなのかも知れんです。
ちゃんと検証してませんが、 setlocale とか std::locale なら通るのかも、とも思うわけです。

https://en.cppreference.com/w/cpp/header/locale
こちらのヘッダですか。

VS2019でビルドすると以下のようなエラーメッセージが出ます。

Severity	Code	Description	Project	File	Line	Suppression State
Error	C2065	'LC_CTYPE': undeclared identifier	sakura	D:\projects\sakura\sakura_core\util\string_ex.cpp	870	
Error	C3861	'_create_locale': identifier not found	sakura	D:\projects\sakura\sakura_core\util\string_ex.cpp	870	
Error	C3861	'_free_locale': identifier not found	sakura	D:\projects\sakura\sakura_core\util\string_ex.cpp	875	
Error	C2065	'LC_CTYPE': undeclared identifier	sakura	D:\projects\sakura\sakura_core\util\string_ex.cpp	891	
Error	C3861	'_create_locale': identifier not found	sakura	D:\projects\sakura\sakura_core\util\string_ex.cpp	891	
Error	C3861	'_free_locale': identifier not found	sakura	D:\projects\sakura\sakura_core\util\string_ex.cpp	895	
Error	C2065	'LC_ALL': undeclared identifier	sakura	D:\projects\sakura\sakura_core\_main\WinMain.cpp	67	
Error	C3861	'setlocale': identifier not found	sakura	D:\projects\sakura\sakura_core\_main\WinMain.cpp	67	

_create_locale についてぐぐった結果以下のページが見つかりました。そこには下記の記述が有ったので、#include <locale.h> しました。

https://docs.microsoft.com/ja-jp/cpp/c-runtime-library/reference/create-locale-wcreate-locale?view=vs-2017#requirements

Routine Required header
_create_locale <locale.h>

なお、WinMain.cpp ファイル内で使っている setlocale についても必要条件は同じです。

https://docs.microsoft.com/ja-jp/cpp/c-runtime-library/reference/setlocale-wsetlocale?view=vs-2017#requirements

Routine Required header
setlocale <locale.h>

なお、::setlocale という記述で検索しましたがそのような記述は見当たりませんでした。

#include <locale>

して、

std::locale

という記述に変えないと頃す!と言われたらすぐに変えるのでお申し付けください。

Copy link
Contributor

@berryzplus berryzplus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

変更内容自体は問題ないと思います。

どうしてこうなった?ということと、
localeヘッダに移行すべきなんじゃ?という点は引き続き、気が向いたら考える、ということで。

@beru
Copy link
Contributor Author

beru commented Dec 11, 2018

・・・なんか外れたこと書いてる気がします。
たぶん、こういう変更があったんじゃないかと思ってます。

No vs ver インクルード方向 説明
1 vs2017以前 clocale ⇒ locale.h locale.h の内容を std 名前空間に展開する
2 vs2019 locale.h ⇒ clocale clocale(std名前空間) を using する
詳しいことは c++er の人にお任せするとして、ざっくりとそんな印象を受けてます。

VS2017環境については berryzplus さんも使っていると思うので、プロジェクトのプロパティの C/C++ の Advanced の Show Includes オプションを Yes (/showIncludes) に変えてビルドしたら Output ウィンドウに #include しているのが全部出るのでそれで実際に確認されると良いと思います。自分はしました。

@berryzplus
Copy link
Contributor

ああ、ちなみに std::locale はtypoです。
うちのIE11からだとコメント編集できないんで放置してました。
(編集するときはわざわざChrome起ち上げてますw)

@ds14050
Copy link
Contributor

ds14050 commented Dec 11, 2018

どうしてこうなった?

beru さんの /showIncludes にヒントがあるのではないでしょうか。

  1. サクラエディタのコードでは明示的に #include <locale.h> していなかったが
  2. インクルードしているある標準ヘッダが内部的に #include <locale.h> していたので問題にならなかった。
  3. VS2019 ではその標準ヘッダが内部的に #include <locale.h> しなくなったので問題が出た。

何も確かめておらず、たぶんですけど。

(追記) 最初の最初に beru さんがもう書いていましたね。>「今まで無くても何で大丈夫だったのかは良く分かりません。どこかの標準ヘッダーで include してるんでしょうか。。」

@beru
Copy link
Contributor Author

beru commented Dec 11, 2018

Review ありがとうございます。Merge します。MinGWでどうして大丈夫だったのかの確認はMSFTがもっと嫌いになったら行おうと思います。

@beru beru merged commit 0773cfd into sakura-editor:master Dec 11, 2018
@beru
Copy link
Contributor Author

beru commented Dec 11, 2018

(追記) 最初の最初に beru さんがもう書いていましたね。>「今まで無くても何で大丈夫だったのかは良く分かりません。どこかの標準ヘッダーで include してるんでしょうか。。」

Issue作成前に原因調査を済ませてIssueの本文に明解な記述をしておかないと、レビューワーもトラブルシューティングの習慣で色々な想像をしてしまうという事ですね。お手数おかけしました。。

@beru beru deleted the missing_include branch December 11, 2018 15:46
@berryzplus
Copy link
Contributor

vs2019では iosbase がxlocaleをインクルードしてくれなくなったってことなんですかね。
std::wistream とか ANSI -> UNICODE 変換が必要なクラスを使うには自前で locale をインクルードせにゃならんのかな・・・。

@beru
Copy link
Contributor Author

beru commented Dec 14, 2018

vs2019では iosbase がxlocaleをインクルードしてくれなくなったってことなんですかね。

VS2019で /showIncludes オプション付けてビルドして出力を確認してみましたが、VS2017の場合と違って、string が istream を include する事が無くなっていました。

string
 xstring
  iosfwd
   yvals.h
    yvals_core.h
     crtdefs.h
     xkeycheck.h

というようになっていて。なお標準ライブラリのパスは
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Tools\MSVC\14.20.27027\
でした。

std::wistream とか ANSI -> UNICODE 変換が必要なクラスを使うには自前で locale をインクルードせにゃならんのかな・・・。

一般論でしか回答出来ませんが、何かの標準ヘッダファイルを include したら違うヘッダファイルも include されるかどうかは処理系依存かもしれないので(規格で決まっているものもあるかもしれませんがいちいち規格参照しながらプログラミングする人はあまりいないと思います)使用する関数やクラスのレファレンスを見て include が必要なヘッダを調べて明示的に書くようにするのが正しいやり方かと思います。面倒なのでよくさぼりがちですけど。

@berryzplus
Copy link
Contributor

vs2019 preview1は結局いれてないので空想でものを言ってます。
何もなければ sp1 が出るまで入れないはず・・・今のノリだとそのうち入れる気がしますが。

一応、必要なヘッダはできるだけ書く派です。

@m-tmatma m-tmatma added this to the next release milestone Feb 3, 2019
HoppingTappy pushed a commit to HoppingTappy/sakura that referenced this pull request Jun 11, 2019
berryzplus added a commit that referenced this pull request Jul 11, 2020
[patchunicode:#694]で追加されたオプションをヘルプに追加する。
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

Successfully merging this pull request may close these issues.

4 participants