C#, C♯, C#相談室 Part96

■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん (ワッチョイ 7633-kUv4)
垢版 |
2021/12/20(月) 11:03:25.88ID:sdn/+VfW0
!extend:checked:vvvvv:1000:512
!extend:checked:vvvvv:1000:512

■Visual Studio 2017 Community(無償の統合開発環境)等はこちら
http://www.visualstudio.com/downloads/

■コードを貼る場合はこちら
http://ideone.com/

■前スレ
C#, C♯, C#相談室 Part94
https://mevius.5ch.net/test/read.cgi/tech/1553075856/

■次スレは>>970が建てる事。
建てられない場合は他を指定する事。
VIPQ2_EXTDAT: checked:vvvvv:1000:512:: EXT was configured
2022/05/20(金) 01:34:48.57ID:eaUqMOJr0
>>285
グローバルフック
2022/05/21(土) 02:00:44.14ID:pmnVOflo0
>>286
サンクス!

WPFで作ってるんだけどグローバルフックを調べて組み込んでみました。
MainWindowをHideするとグローバルフックが効かなくなるので
MainWindowは描画をせずグローバルフックを動かして、
子WindowにWindowを描画してHide/Showするようにしたらなんとか形になりました。
こんなのでいいのかなんだかすっきりせず。
2022/05/21(土) 10:29:06.89ID:XiDxIIx00
>>287
なんでだろ?メインウィンドウからフック仕掛けてる?
Formsの頃の記憶だけど、Application.run以前にSingletonな管理クラス作ってやってた。
そいつからイベント送られてくるようにしてたよ。
それで問題なかったはずだけど、なんか変わったんのかな。
289デフォルトの名無しさん (ワッチョイ 8b01-H9jD)
垢版 |
2022/05/21(土) 14:05:38.07ID:2Lltosx/0
以前HotKeyで作ったけど中身はグローバルフックなんかな
2022/05/21(土) 15:40:41.47ID:4jCCGHc40
Utf8Parser.TryParse(span, out DateTime date, out _, 'O')について聞きたいんだけど、以下の文字列はUtf8Bytesとして
"2022-01-01T00:00:00.0000000Z" ← 28文字のこれなら正常に成功するのに
"2022-01-01T00:00:00.000000Z" ← 27文字のこっちは失敗する

DateTime.TryParseなら後者も成功するんだけどこれはUtf8Parserがポンコツってこと?
それともDateTime.TryParseがオーバー解析してくれてるだけで28文字未満の"O"形式のDateTime投げてくる方が非常識?
2022/05/21(土) 15:55:42.97ID:cfNQUnEf0
>>290
https://github.com/dotnet/runtime/blob/57bfe474518ab5b7cfe6bf7424a79ce3af9d6657/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Date.O.cs#L175
27文字目は数字以外だとエラーになるっぽいね
2022/05/21(土) 16:15:24.74ID:ec9yQBCj0
>>290
失敗しても仕様の範囲内ぽい

> ラウンドトリップ ("O"、"o") 書式指定子
> "O" または "o" 標準書式指定子は、DateTime 値の "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffffffK" カスタム書式指定文字列と
> DateTimeOffset 値の "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffffffzzz" カスタム書式指定文字列に対応します。
293sage (ワッチョイ cebb-8jyA)
垢版 |
2022/05/21(土) 16:43:22.42ID:0fNBsESd0
27文字のが来る状況あるんだっけ?
2022/05/21(土) 18:38:40.30ID:hT1fnPAH0
>>288
レスありがとう!
MainWindowからフックしています。
シングルトンにはしてないですが、MainWindowは生きているので、
フック自体は破棄されていませんが、どうもダメでした・・・
2022/05/21(土) 21:45:54.24ID:8HM5gfhu0
>>285
特定のキーで表示ならSystem.Timers.Timer使ってGetKeyStateとかでキー入力監視
キーがヒットしたらタイマー止めて目的のウィンドウを表示
ずっと監視するのが嫌でなければ実装はかなり楽な方かと
アプリランチャーならタスクトレイに格納してマウスクリックで表示させての方が使いやすい気がするけど
2022/05/22(日) 01:09:06.35ID:7HW4nX7o0
RawInputでいいんじゃね
2022/05/22(日) 01:44:20.92ID:xpEgvjj30
>>285 です

>>288 さんの
>Application.run以前に
というのをヒントに、WPFなのでrun()は無いけど、Appにコンストラクタを記載しその中でフックを起動して、
キーダウンのイベント内でMainWindowを取得し制御する事で上手く行きました!
その他手法含めご教授してくださった方々有難うございます!
2022/05/22(日) 09:35:29.30ID:gmOf9ICx0
>>291-293
現状だと28文字未満だったらUtf16に変換してDateTimeの方でやるしかないか
そこそこ知られてるWebサービスのAPIがたまに桁詰められて27文字の投げてくるんだよね
2022/05/22(日) 10:21:24.48ID:GyF0oANxM
悪いけど、Webのレスポンスだったら最初から全部UTF16でやっても全くパフォーマンス変わらないと思うよ
2022/05/22(日) 11:48:59.69ID:gmOf9ICx0
>>299
そんな大きなペナルティがあるとは思ってないけど全く変わらないというのはどういう原理で?
JsonDocument.Parse(response.Content.ReadAsStream())みたいな感じでやってるけど、これだとUtf8のままパースされてるよね
2022/05/22(日) 15:34:34.14ID:Nn/6kHB8d
用途次第じゃない?
HTTPSの通信に比べればJSONのデコードなんか誤差だから単一の処理で見るなら全く意味ないだろうけど、
もし大量のリクエストを捌くサーバーを作っているならCPUやメモリの使用率を削減することでサーバーのインスタンス数を削減できるかもしれない
2022/05/22(日) 16:53:52.96ID:7HW4nX7o0
そこまでシビアなら、他にもっと先に見直す所があると思うけど
2022/05/29(日) 18:01:05.65ID:Gx8AtDBv0
WindowsFormはそれなりに少し経験はあるんですが行き詰まっているので相談です

centos7にapach上で、これまでhttpd.confにAliasで特定のドキュメントルーツを設定して
phpでつくったWebアプリをいくつか動かしている環境があり、ここに新たに
Blazorサーバやってみようと、dotnetインストールしてrunまではできてます
(配置したdllを実行するserviceをつくってそれも起動可能な状態)

phpでつくったアプリのようにAliasで簡単にできるかなと思ってたらそうでもなく
サイトググるとVirtualHostの例がちらほら

example.com/app1 ・・・ var/www/app1 にphpアプリ配置
example.com/app2 ・・・var/www/app2 にphpアプリ配置
example.com/blazor を新たに配置するにはどの辺調べればいいですかね
MSのドキュメントやBlazorや先日でたNET6の書籍とか見ながらいろいろやってはみたものの
どれもうまくいかず、行き詰まっております(方向性を見失ってます)
リクエストきたものをkestrelに渡してやらなきゃいけないってのはなんとなく理解してますが
VirtualHostとリバースプロキシをきちんと理解しないでできないですかね
2022/05/29(日) 18:02:59.94ID:Gx8AtDBv0
ドキュメントルーツ・・・ドキュメントルートです
すみません
2022/05/29(日) 19:36:38.11ID:kVtoPC2XM
IISでホストしてApache側でVirtualHostの指定でリバースプロキシすりゃいいよ
頭悪い構成だが、その調子だとリバースプロキシの設定はなんとかなってもどうせdotnetアプリを常時起動する方法が見当つかないんだろ?
2022/05/29(日) 20:08:21.68ID:DRuRn6I70
>>303
リバースプロキシ使用時はhttps使わない構成にしなきゃダメだぞ
2022/05/29(日) 20:15:46.80ID:1ETRcw7wM
>>303
すでにデーモンとして動かしてるならリバースプロキシするだけ
ググって適当にコピペでまあいける
本番だったらちゃんと理解してやったほうがいいと思うけど
2022/05/30(月) 04:15:11.38ID:JkhndRSZa
数か月ぶりでここ覗いてみたけどまだ結構人がいるみたいでちょっと安心したw

以前は旧FireFoxのChaikaってアドオンをだましだまし使ってたんだが、(それがいよいよ
使えなくなったのが来なくなった理由)今回JaneStyleを入れてみたが、作者さんを批判する訳じゃないが、
UIは25年前のWin98時代のものだし鬱陶しいエロ広告は表示されるし結構萎えるなこれ

C#といっこも関係ない話題ですまん
2022/05/30(月) 08:09:38.08ID:n9/aIkj20
みなさんレスありがとうございます

>>305
serviceつくって常時起動はできてるかなと思います
>>306 >>307
稼働WEBサーバはhttpsのみなので、ってことは今の構成でそのままっていかないんですね
(Rewriteでhttpをhttpsにしている)
ネットの設定例にある、http://localhost~; をhttpsにしていましたが

ネットで見つけられた設定例って、そのサーバの全アクセスをリバースプロキシさせるようなものがほとんどで
自ドメインの特定のアドレス(上でいう、example.com/blazor)だけを
リバースプロキシさせてdotnetが受け取れるようにってできないもんでしょうか?
できるということであれば、どうにかして調べます

バーチャルホストは複数のドメインを扱ってて、Aliasは同じドメインで複数のドキュメントルートを扱えると
考えているので、やりたいことはバーチャルホストでできないんじゃないかなと思ってるんですが
サブドメインにしちゃえば1つのドメインでもやれますかね
2022/05/30(月) 08:44:27.76ID:terzLTfjM
できるよ
2022/05/30(月) 14:27:32.28ID:rKCebS3v0
>>310
ありがとうございます

後者の方はhttpでうまくできました
ただ、実際はユーザーからhttpsでつながせたいのですが
証明書がないのでブラウザで開いても動作確認できず
メインドメインのSSL証明書だと、ワイルドカードだと割高なのでドメインを
追加するしかないかなと思うのですが、
VirtualHostの設定内に取得した証明書の設定書いてやれば
httpsで動作させることができると考えてもいいんでしょうか?
下みたいな感じで。前者の方ならそんな手間も費用もいらないんでしょうが、方法がみつからない

<VirtualHost *:443>
ServerName hoge.example.com
ProxyPreserveHost On
ProxyPass / https://localhost:5001/
ProxyPassReverse / https://localhost:5001/
RewriteEngine on
RewriteCond %{HTTPS} on
RewriteCond %{HTTPS:UPGRADE} ^WebSocket$ [NC]
RewriteCond %{HTTPS:CONNECTION} Upgrade$ [NC]
RewriteRule /(.*) ws://127.0.0.1:5001/$1 [P]
2022/05/30(月) 14:30:41.80ID:rKCebS3v0
SSL部分書き忘れましたが、書き方は省略します

SSLEngine on
SSLCertificateFile [crtのパス]~~以下略
2022/05/30(月) 15:23:01.71ID:/JK2MYXZ0
俺はPHPも使えるんだぜ
すげーなおれ
2022/05/30(月) 16:31:04.22ID:rKCebS3v0
>>311はいちど撤回します

Program.csでapp.UseHttpsRedirection()が抜けてたのでそれを加えつつ
前者の方をLocationでなんとかhttpsでの表示までたどり着きましたが
どうも完全な動作をしてない様子です
(Blazorの学習用のテンプレートでメニューやテキストだけだけ羅列された状態)

<Location "/blazor">
ProxyPreserveHost On
ProxyPass http://localhost:5000/
ProxyPassReverse http://localhost:5000/
RewriteEngine on
RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]
RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC]
RewriteRule /(.*) ws://127.0.0.1:5000/$1 [P]
</Location>
もう一息な感じなんですが・・・
2022/05/30(月) 19:40:46.77ID:n9/aIkj20
解決しました
サーバー側でなく、ソース側の修正で表示できました
2022/06/18(土) 22:52:15.42ID:5N4YYnEs0
古い話題で恐縮なんですが質問です。
https://docs.microsoft.com/ja-jp/dotnet/standard/asynchronous-programming-patterns/calling-synchronous-methods-asynchronously#executing-a-callback-method-when-an-asynchronous-call-completes

IAsyncResult result = caller.BeginInvoke(3000,
out dummy,
new AsyncCallback(CallbackMethod),
"The call executed on thread {0}, with return value \"{1}\".");

begininvokeで呼び出されたのが終わるとき、callbackmethodが呼び出されることまではわかりました。
2022/06/18(土) 22:53:28.07ID:5N4YYnEs0
途中送信すみません。

callbackmethodを見ると引数にIAsyncResult arとありますが、これはどこから来たものでしょうか?
begininvokeでは呼び出す関数を指定してはいますが、その関数に渡す引数は指定していないように見えます。

よろしくお願いします。
2022/06/19(日) 00:17:36.07ID:TrF8/kJeM
https://docs.microsoft.com/ja-jp/dotnet/api/system.asynccallback?view=net-6.0
のとおり、AsyncCallbackは
「public delegate void AsyncCallback(IAsyncResult ar);」
と定義されてるデリゲートだけど・・・?
2022/06/19(日) 01:35:57.45ID:NHHRNcNt0
関数ポインタというか関数オブジェクト
2022/06/19(日) 08:04:27.42ID:Nk1h87ob0
>>317
> callbackmethodを見ると引数にIAsyncResult arとありますが、これはどこから来たものでしょうか?
.NET側で作成して必要な情報をセットしてCallbackMethodを呼び出すようになってるだけだよ
2022/06/19(日) 10:47:43.19ID:O3VLYjye0
>>318
あーいやですからcallbackmethodが実行されるときの引数arはどこにあるのかという話で

>>320
引数は勝手に.NET側が指定してくれるということでしょうか
2022/06/19(日) 10:52:20.66ID:nWWcJPGW0
セグメント的な意味ならスタックじゃね?
2022/06/19(日) 11:41:03.45ID:7K+FVRoS0
この質問の的はずれな感じ初心者だろうからこっち行け
https://mevius.5ch.net/test/read.cgi/tech/1655422932/l50
2022/06/19(日) 12:21:28.04ID:+YnI+5A8a
あなたの心の中にあるよ
2022/06/19(日) 14:14:38.43ID:YZZ11uFp0
CのDLLから呼び出し規約cdeclのコールバック用の関数ポインタを要求された場合、
C#のデリゲートを受け渡し出来る方法、もしくはC#側でcdeclの関数を作る方法はありますか?
2022/06/19(日) 15:01:29.91ID:mFXr9uBN0
GetFunctionPointerの説明にはDelegateの定義にUnmanagedFunctionPointerAttributeをつけるとCallingConventionを制御できると書いてある
2022/06/19(日) 15:23:57.91ID:YZZ11uFp0
なるほど、属性で指定するんですね
ちょっと試してみます
2022/06/26(日) 10:39:56.55ID:UB4e87n30
半角の#は制御文字で
しょうもないバグの要因になるから使いたく無いんだよな
なんで#なんか名前に使ったん?
2022/06/26(日) 10:47:20.23ID:ljaQjS590
C++++って呼べばいいと思うよ
2022/06/26(日) 10:53:50.00ID:mb7mYMEr0
>>328
どういう意味の「制御文字」?制御文字というとふつうは0x00-0x1fを想像してしまうが。
2022/06/26(日) 11:09:18.97ID:4GsWpWI+M
non-alphanumeric
2022/06/26(日) 11:17:43.56ID:NLYG3vIc0
C++はいいのか?
2022/06/29(水) 11:22:11.80ID:rVQ8qMbxd
まあ#よりはマシなのでは
ただしcppって略してc preprocessorと被せるのは許さん
2022/06/29(水) 11:41:40.54ID:B8mpBogv0
どう見ても問題になるのは+の方
正規表現で邪魔になる
2022/06/29(水) 11:54:18.32ID:anfh1Uacr
c+4ってなるよりはマシ、、、
もっといいセンスあったやろなあ今更やが
2022/06/29(水) 20:32:03.37ID:5BRKVkZj0
おジャ魔女どれみ#
2022/06/29(水) 21:36:03.92ID:ZbbkHISNa
しょうがないんだ
あの時代は自称ヒッピーのキモオタ世界だったし、Microsoftはすべての商品名の他に社名までが究極的にゴミクソ脱糞太郎だからな
何が.NETだボケ
2022/06/29(水) 22:13:24.27ID:MHsZYoUcd
マイクロソフトボブおじさんおったよな
339デフォルトの名無しさん (アウアウウー Sad3-7uco)
垢版 |
2022/06/30(木) 08:36:25.96ID:vvnSi9+Ba
csharpでよかったのに
2022/06/30(木) 08:44:23.01ID:mxGmIKrnd
+を四つ組み合わせたんやろ
2022/06/30(木) 09:02:49.53ID:RS+78JOl0
+++だとモデムがコマンドモードに入って具合悪いからな
342デフォルトの名無しさん (アウアウウー Sad3-sbT5)
垢版 |
2022/06/30(木) 11:25:19.25ID:l3rHcZB/a
Cpp って C pre processor のことだろ
343デフォルトの名無しさん (ワッチョイ 3f3e-sii1)
垢版 |
2022/06/30(木) 23:55:35.01ID:yANzD8P40
底辺職業ランキングで c# プログラマが一位を獲得。

底辺職業の条件 3つ

1. 同じことを繰り返す。
for ループつかってるよね。

2. 誰でもできる
スタックオーバーフローを見れば、c#プログラミングなんて誰でもできる。

3. 体力勝負

https://i.imgur.com/0BRVa3M.jpg
c# アプリケーションのビルドが含まれているとのこと。
2022/07/01(金) 02:57:28.78ID:I3o7r2ai0
はえ~最近の生ゴミは掲示板に投稿できるんですね
2022/07/01(金) 15:22:31.26ID:svwhpzKm0
VisualStudio 2015 ターゲットフレームワーク .Net Framework 4.5.2
Shownイベントで発生した例外をApplication.ThreadExceptionでキャッチ
したいのですが期待する例外が届きません。
何が原因なのでしょうか。

public partial class Form1 : Form {
[STAThread] static void Main() {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.ThreadException += ShowException;
Application.Run(new Form1());
}
private static void ShowException(object sender, ThreadExceptionEventArgs e) {
MessageBox.Show(e.Exception.ToString());
}
private void Test() {
try {
throw new Exception("1 起点");
}
catch (Exception ex) {
throw new Exception("2 期待する例外", ex);
}
}
public Form1() { InitializeComponent(); }
private void Form1_Shown(object sender, EventArgs e) { Test(); } //1が届く
private void button1_Click(object sender, EventArgs e) { Test(); } //2が届く
}
2022/07/01(金) 16:11:44.24ID:3n4aX0eh0
なぜサポート切れのバージョンを…
2022/07/01(金) 20:14:48.14ID:dkEku/by0
古いのを使わないといけないプロジェクトに放り込まれる辛さってあるよね……
客先行ったらvisual studio 2010だと言われたときの絶望
2022/07/02(土) 00:00:46.05ID:thG8tJ450
>>345
https://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/Form.cs,4908
理由は分らないけど↓が原因っぽい
this.BeginInvoke(new MethodInvoker(CallShownEvent));

試しにbuttun2を追加して以下のコードを実行したら同じ現象が発生した
private void button2_Click(object sender, EventArgs e) { BeginInvoke(new MethodInvoker(Test)); }
2022/07/02(土) 04:41:25.58ID:F5+MIbFGa
>>347
使わなければいけない理由って何だろう?慣例で使い続けてるのなら承諾得てバージョンアップするべきだし、予算の都合なら上を説得して稟議出すべき
2022/07/02(土) 07:08:15.65ID:39Wf3KWj0
>>349
自社のプロダクトなら何とかなるが他社のは無理だ。
未だにVB6使ってる所もあるし。
.NET Framework 4.8はVB6と同じようになると思う。
2022/07/02(土) 09:45:46.45ID:At3W7bIA0
>>349
受託でも自社でもいいけど売り物の開発したことないのか?
新しいVSでる度に新バージョンに移行なんてやってられないぞ
なんのためにMSがサブスクで過去バージョン使えるようにしてると思ってるんだよ
352デフォルトの名無しさん (スッップ Sdaa-8NLY)
垢版 |
2022/07/02(土) 10:15:43.97ID:2EN85JI9d
VS2022スレに書くか迷ったけどスレの勢いがありそうなこちらに

razorページ書いてて、コード部分や変数部分が色が変わるけど、ページスクロールさせていくと一定の場所からプロパティの色がとぶ
上に戻ると表示は直る、消えているときは数秒ごとに付くべき色が一瞬ちらつく
メソッドの定義なんかは色が付いたまま

考えられる原因ってありますかねぇ
伝わるかどうか不安ですが、、、
2022/07/02(土) 10:47:08.32ID:Nqfsnfr90
VSが力尽きた
2022/07/02(土) 10:49:08.06ID:3bhPD9xQ0
メモリを32GBは積まないと無理だぞ
2022/07/02(土) 14:01:01.27ID:qdkCWbbw0
>>347
VS2010なら未だマシ。.slnファイルは2010以降なら概ね互換性あるから。
2005とか2008なんて案件に放り込まれた暁にゃ...

>>349
UIコンポーネントのデザイナがそれ以降のVSだと動かないとか。
2022/07/02(土) 15:55:12.45ID:Hl2BGrbY0
>>349
上がVSとターゲットビルドバージョンの区別がついてないから
2022/07/06(水) 10:36:39.11ID:Eu330xAsa
C#の関数ポインタでstaticなメソッド(GC管理下)のアドレスを保持するとき、GCによってアドレスが移動して参照出来なくなる、といったことはありえますか?
2022/07/06(水) 12:46:13.50ID:I0+9VWih0
関数のアドレスが移動することはない
dllのアンロードにより消え去ることはあり得るがそれはプログラマの責任
2022/07/06(水) 13:18:48.55ID:Eu330xAsa
>>358
ありがとうございます。うまく調べられなかったので助かりました
2022/07/06(水) 14:13:11.32ID:L8iINPbs0
いえいえ
2022/07/06(水) 16:59:30.96ID:4c2uM/uj0
あたらなければどうということはない
2022/07/06(水) 22:44:44.73ID:VxYrHSBA0
夏は〆鯖に限るな
2022/07/06(水) 23:10:42.62ID:c/WBgrCD0
猪&鹿&鳥の刺身とセットでドゾー
2022/07/07(木) 05:50:37.22ID:Zmd+D9aAa
蝶もうまいよ
365デフォルトの名無しさん (スプッッ Sd43-UXSH)
垢版 |
2022/07/11(月) 08:41:37.48ID:9VbmZwXxd
blazor触ってるんですが、デバッグでチェックしていると
開発ツールでbodyタグの最後に
live-preview-rootというタグが入って
hiddenのdiv内にsrcがYouTubeのアドレスの入ったiframeが入るんですが、なんですかねこれ、、、

アドレスはyotubeのあとにstaticやらscheduleなどが続いていて、踏んでもソースがでるだけ
ページ表示させただけでは出てなくて、開発ツールの要素にだけ出てくるのですが、ビルドしてサーバに置いた場合は出ない、、、あくまでもデバッグ中のページのみ

そもそもプロジェクト内にはYouTubeの文言はないし、クロームでもedgeでもでます
vsの仕様なのか、なんなのか、、、
心当たりある方いますか?
366デフォルトの名無しさん (スプッッ Sd43-UXSH)
垢版 |
2022/07/11(月) 08:44:44.50ID:9VbmZwXxd
ちなみにテンプレートからの新規作成プロジェクトの時点出てるので、ソースそのものの問題ではないと思うのですが
2022/07/11(月) 09:04:43.64ID:DQKxRie+M
Choromeだけじゃなくて他のでもひらいてみ
368デフォルトの名無しさん (スプッッ Sd43-UXSH)
垢版 |
2022/07/11(月) 12:21:14.47ID:iwvb/poMd
>>367
最初に気づいたのがEdgeで、Chromeでも同じでした
Firefoxだと、live-preview-root #shadow-root(open)までで
iframeにYouTubeへのリンクは出ませんでした
EdgeってChromeベースで、Googleのスクリプトみたいなのが
勝手に差し込まれるんですかね、、、
2022/07/11(月) 19:29:42.75ID:plmq8H3m0
たぶん、便利な開発用ツールか何かじゃないの?
2022/07/30(土) 18:54:16.32ID:jErZjSQja
皆さん、インクリメントとデクリメントについてどのようにお考えですか?
個人的にこれを使うことに抵抗があります(無知が理由で)
特に、内部メソッド等にローカルなintを渡して処理後に1だけ加算したいときってよくあると思うんですが、
int num = 0;
M(num); num++; これと
M(num++); これは、本当に常に一致してくれるんでしょうか?
IL上での違いはこんな感じでした

// M(num);
IL_0003: ldloc.0
IL_0004: call void C::'<M>g__M|0_0'(int32)
IL_0009: nop
// num++;
IL_000a: ldloc.0
IL_000b: ldc.i4.1
IL_000c: add
IL_000d: stloc.0
IL_000e: nop

// M(num++);
IL_0003: ldloc.0
IL_0004: dup
IL_0005: ldc.i4.1
IL_0006: add
IL_0007: stloc.0
IL_0008: call void C::'<M>g__M|0_0'(int32)
IL_000d: nop
IL_000e: nop

これって最終的には同じコードなんでしょうか?
可読性以外の差異がありましたら教えていただけないでしょうか。よろしくお願いします
2022/07/30(土) 19:14:00.13ID:Syvf1c+c0
そんなに気になるならデバッグで逆アセンブルコードでも見ればええやん
2022/07/30(土) 19:16:04.98ID:1KJkNmDVM
>>370
引数の値の評価が違う

前者
numを評価(変数numの値は0)→M呼出し(引数の値は0)→num++を評価(変数numの値は1)

後者
num++を評価(変数numの値は1)→M呼出し(引数の値は1)→変数numの値は1
2022/07/30(土) 19:48:51.18ID:Qp1EMWGTM
あれ、
「m(++num)」ってインクリメントが前なら引数が加算後の1になるのは分かるんだけど
「m(num++)」だと加算前の0が引数になるんじゃ?と思った

個人的にはインクリメント結果を代入したり引数にしたりする使い方は禁忌とすべきだと思う
使っていいのは単項目で「i++;」みたいなことをするときだけにしておきたい
できることならfor (var i=0; i<length; i++)みたいな定型for以外は面倒でも
「i = i + 1;」と書かせたいくらいだなあ
2022/07/30(土) 19:49:39.77ID:x7sp4WG30
>>372
後者の説明間違ってるぞ。それじゃ++numの場合だ。
num++だから引数は0
2022/07/30(土) 20:09:53.26ID:2QzW5DDXM
言語仕様としては厳密には未定義なのかも知れないが、少なくとも>>370のILの中身見た限りでは引数評価後に関数呼び出しが行われる様に実装されてる
2022/07/30(土) 20:14:24.72ID:2QzW5DDXM
未定義というより環境依存かな
大抵の言語では関数の呼出しと引数の評価順は明確化されてないのでいわゆる副作用として扱われる
2022/07/30(土) 20:48:41.87ID:x7sp4WG30
>>375
ちゃんとIL読みなよ
後者はnum++の評価自体は関数呼び出し前だけど、その前にdupが入ってるから、引数は評価前のnumの値(0)でしょ
2022/07/30(土) 22:50:30.62ID:zHogqexf0
>>376
複数の引数の評価順が未規定なのはよくあるけど引数の評価前に関数呼出するような言語なんてあったっけ?
2022/07/30(土) 22:54:13.72ID:Syvf1c+c0
そういう読み違いが発生しそうなコーディングすんなって事でいいのでは
2022/07/30(土) 23:20:24.67ID:zHogqexf0
言語仕様の話とコーディングルールの話をごっちゃにすんなよ
2022/07/30(土) 23:41:50.24ID:Syvf1c+c0
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/expressions#1141-general

Operands in an expression are evaluated from left to right.
Example: In F(i) + G(i++) * H(i),
method F is called using the old value of i,
then method G is called with the old value of i, and,
finally, method H is called with the new value of i.
This is separate from and unrelated to operator precedence.
2022/07/31(日) 00:12:35.62ID:UwyiR8NW0
>>381
それは演算子のオペランドの評価順
今回の件とは別の話で、未規定の言語(例 C言語)もある
2022/08/01(月) 13:24:37.35ID:kNeknzrgd
複数の評価が連続した場合の副作用完了点は大抵の言語で規定されてない
例えば上の様に関数に与える引数の中の式で副作用を起こす場合これに該当する
2022/08/07(日) 00:16:44.36ID:pGypWfdHM
VC++は未定義動作でーすでバージョン変わったら評価順も変わって結果が変わる

cout <<i++ <<i++<<i++<<i++<<i++<<i++;
2022/08/08(月) 16:40:20.17ID:Zu2CvCE20
C++は17か20で言語として評価順定義されるようになった
2022/08/08(月) 16:57:09.86ID:0tCAtbwJ0
この辺の仕様全然詳しくないけどさ
++numとか分かりにくいし行儀悪いし個人的にはいらないと感じる
num++だけありゃいい
for文の++iteとかこんがらがるからマジやめてほしい
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

ニューススポーツなんでも実況