■ このスレッドは過去ログ倉庫に格納されています
C++相談室 part161
- 1 :デフォルトの名無しさん:2022/05/21(土) 21:23:29 ID:kYXfaM+5.net
- 前スレ
C++相談室 part160
https://mevius.5ch.net/test/read.cgi/tech/1649979572/
- 948 :デフォルトの名無しさん:2022/10/24(月) 02:10:09.65 ID:JEuztk1D.net
- 9か5かってのは説明上の話で、実際は未定義で鼻から悪魔だから9でも5でも0でも-1でも42でも4394967295でもどんな可能性もあった
今の規格では必ず9になった
- 949 :デフォルトの名無しさん:2022/10/24(月) 02:11:12.04 ID:b0depGja.net
- https://ja.cppreference.com/w/cpp/language/eval_order
スカラーオブジェクトに対する変更にしかUB関係なくね?
- 950 :デフォルトの名無しさん:2022/10/24(月) 02:19:24.78 ID:od8Ytdiw.net
- operator<<が触ってるcoutのメンバ変数やグローバル変数にスカラーオブジェクトが一切含まれてなければ関係ないけど普通はそんなはずは無い
- 951 :デフォルトの名無しさん:2022/10/24(月) 07:45:35.99 ID:bUVy0t4Y.net
- テキストがバラけたり変数の並び順を変えられなくてi18n対応が困難になるのがiostreamの一番の問題かな
- 952 :デフォルトの名無しさん:2022/10/24(月) 08:12:37.76 ID:OQANp5iI.net
- >>946
実際どっちが正しいかは知らんが説明がよくわからん。
cout << foo << bar の例えに (a+=2)*=3 を持ってくるのは正しいのか?
- 953 :デフォルトの名無しさん:2022/10/24(月) 09:31:36.65 ID:9tRgjj9T.net
- >>946
> それが「単一式で同じオブジェクトを2回変更したら未定義」というもの
C++11 より前のシーケンスポイント(副作用完了点よるルールの話だとしても関数呼び出しの前後には
シーケンスポイントが入るので cout の operator<< で未定義動作が起こるような話にはならない。
- 954 :デフォルトの名無しさん:2022/10/24(月) 09:49:55.97 ID:9tRgjj9T.net
- >>946
「rangesのパイプでoperator|のチェーンの検討をしてるとき」とか言ってるから
本気で C++17 改定前の話をしてるっぽいなぁ。
> それが「単一式で同じオブジェクトを2回変更したら未定義」というもの
ここから間違い。 C++11 以降は "sequenced before" の順序関係に基づくルールになっていて、
そんな大雑把なルールではない。
> 例えば(a+=1)+=1はどっちの1を先にaに足してもいいが、そういう自由度がある時点で未定義というルールになっていた
C++11 時点で代入式の値取得は代入より後になると規定されているよ。
https://timsong-cpp.github.io/cppwp/n3337/expr.ass#1
> In all cases, the assignment is sequenced after the value computation of
> the right and left operands, and before the value computation of the assignment expression.
関数呼び出し前後に順序関係もある。
https://timsong-cpp.github.io/cppwp/n3337/intro.execution#15
> When calling a function (whether or not the function is inline), every value
> computation and side effect associated with any argument expression,
> or with the postfix expression designating the called function, is sequenced before
> execution of every expression or statement in the body of the called function.
- 955 :デフォルトの名無しさん:2022/10/24(月) 23:16:53.41 ID:Fd/xLFmz.net
- どなたか、clangコンパイラのソースコードで、main()関数がどのソースファイル
にあるか分かりませんか?
- 956 :デフォルトの名無しさん:2022/10/24(月) 23:38:51.20 ID:uNnUskRf.net
- grepで始めよう
新しい検索を
- 957 :デフォルトの名無しさん:2022/10/24(月) 23:50:22.01 ID:Fd/xLFmz.net
- >>956
もちろんgrepはしていますが、
test用のソースコードなどに大量に出てきてしまうのでどれか分からないのです。
探しているのですが、むしろ、clangコンパイラ自体のmain関数は存在して
無いのではないかと思えてしまいます。
- 958 :デフォルトの名無しさん:2022/10/25(火) 00:20:05.85 ID:ALWiFOZj.net
- >>957
grepでtestっぽいのを除外していけば見つけられると思うけど、
スマホでgithub見た感じdriver/tools/driver.hppじゃね
- 959 :デフォルトの名無しさん:2022/10/25(火) 00:20:30.61 ID:ALWiFOZj.net
- まちがえたdriver.cppね
- 960 :デフォルトの名無しさん:2022/10/25(火) 15:32:20.93 ID:VfaC5Wzc.net
- このコードでfunc(a)だけがコンパイル通らないんだけどどう対策すれば綺麗な感じになる?
ユニバーサル参照の受け取りのとこでT=int&がstd::integralを満たさないのが原因なんだけど
integral_or_lrefコンセプト作るしかない?
#include<utility>
#include<concepts>
template<std::integral T>
void func(T&&);
int main(){
int a=0;
func(0);
//func(a);
func(std::move(a));
}
- 961 :デフォルトの名無しさん:2022/10/25(火) 15:33:30.00 ID:Ct0eul8Q.net
- 超初心者+わかりにくい文章で、ごめんなさい。
今までは、.NetFramewor4.72でWinFormを使って実装していました。
今、.Net6.0 の WinFormで実装する必要が出てきたので
.Net6.0 で実装しています。
.NetFramewor4.72 でWindowsBaseの参照の追加で使えていた
System.Windows.Threading.Dispatcher が
.Net6.0 では、「依存関係」の「COM」で設定しようとしても、
WindowsBaseが表示されず、WindowsBaseを設定できなくて
System.Windows.Threading.Dispatcherが使えなくて、困っています。
同じような課題を諸先輩方は
どのように解決されましたか?
- 962 :デフォルトの名無しさん:2022/10/25(火) 15:37:45.19 ID:VfaC5Wzc.net
- >>961
C#はこっちで
https://mevius.5ch.net/test/read.cgi/tech/1639965805/
- 963 :デフォルトの名無しさん:2022/10/25(火) 15:39:23.68 ID:Yrt8fN18.net
- CLIはこっちか?
- 964 :はちみつ餃子 :2022/10/25(火) 15:54:18.45 ID:kIG3TWOj.net
- >>960
参照を剥がすのを入れるのが常道じゃないかな?
template<class T>
requires std::integral<std::remove_reference_t<T>>
void func(T&&);
- 965 :デフォルトの名無しさん:2022/10/25(火) 16:15:10.24 ID:2SxwmPby.net
- >>962
大変失礼しました。
アドバイスありがとうございます。
- 966 :デフォルトの名無しさん:2022/10/25(火) 18:06:59.76 ID:NHQVrZyF.net
- そういうとき脳死でstd::decay使っちゃうけどあんま行儀良くないかな
- 967 :デフォルトの名無しさん:2022/10/25(火) 18:13:31.96 ID:UwkZi3XT.net
- >>958
ありがとう。関数名が main() ではなく、
clang_main()
なんですね。
cmakeすると、これがすぐ呼び出されるような main() 関数が
作られるようです。
cmakeがどういう仕組みでそうやっているのかは分かりませんが。
- 968 :デフォルトの名無しさん:2022/10/25(火) 18:15:07.22 ID:UwkZi3XT.net
- >>958
古いWzEditorのgrepを使ってるんですけど、除外フォルダが指定できないんです。
何かいい方法は有りますかね。
- 969 :デフォルトの名無しさん:2022/10/25(火) 20:38:52.33 ID:m6AygvvN.net
- どっちかってーと リンカで実行時のエントリポイントを細工してるんじゃないのかな?
- 970 :デフォルトの名無しさん:2022/10/26(水) 01:01:19.91 ID:lrkwz/4D.net
- 追加質問です。
llvm のソースの中に、以下の様に、
配置 new に似ていてもそれとは違うような new 演算子の使用方法が
有りますが、分かる人いますか? 例えば、
new (2) CatchReturnInst(CatchPad, BB, InsertBefore);
は、配置 new の new (p) T(引数列) に似ていますが、
p の位置は、アドレスを指定することになっているのに、
「2」という整数値を指定しています。
llvm-project-main/llvm/include/llvm/IR/Instructions.h
の
class CatchPadInst : public FuncletPadInst {・・・}
の中の
static CatchPadInst *Create(Value *CatchSwitch, ArrayRef<Value *> Args,
const Twine &NameStr = "",
Instruction *InsertBefore = nullptr) {
unsigned Values = 1 + Args.size();
return new (Values)
CatchPadInst(CatchSwitch, Args, Values, NameStr, InsertBefore);
}
class CatchReturnInst : public Instruction {・・・}
の中の
static CatchReturnInst *Create(Value *CatchPad, BasicBlock *BB,
Instruction *InsertBefore = nullptr) {
assert(CatchPad);
assert(BB);
return new (2) CatchReturnInst(CatchPad, BB, InsertBefore);
}
- 971 :はちみつ餃子 :2022/10/26(水) 01:03:41.11 ID:UI6BPQPg.net
- >>970
placement new だろ。
- 972 :デフォルトの名無しさん:2022/10/26(水) 01:09:20.17 ID:AzbtQsoy.net
- >>967
ごめん、tools/driver/driver.cppだった。321行目あたりにmainあるけどこれじゃないの?
>>968
msysとかgit bashとかwslのgrepを使う、じゃダメ?vscodeでも除外設定はできるけど
- 973 :デフォルトの名無しさん:2022/10/26(水) 01:53:26.73 ID:U/bwzoe1.net
- >>971
以下の様に、new (Us) CatchReturnInst(引数列)は、
Userクラスの operator new(Size, Us) を使っていて、
で、Usには、アドレス値ではなく、Use 型の個数を入れるようです。
通常の operatoe new()では、第二引数はアドレス値です。
class CatchReturnInst : public Instruction {・・・};
class Instruction : public User,
public ilist_node_with_parent<Instruction, BasicBlock> {・・・};
void *User::operator new(size_t Size, unsigned Us) {
return allocateFixedOperandUser(Size, Us, 0);
}
void *User::operator new(size_t Size, unsigned Us, unsigned DescBytes) {
return allocateFixedOperandUser(Size, Us, DescBytes);
}
void *User::allocateFixedOperandUser(size_t Size, unsigned Us,
unsigned DescBytes) {
・・・
uint8_t *Storage = static_cast<uint8_t *>(
::operator new(Size + sizeof(Use) * Us + DescBytesToAllocate));
・・・
}
- 974 :デフォルトの名無しさん:2022/10/26(水) 01:56:10.10 ID:U/bwzoe1.net
- >>972
>ごめん、tools/driver/driver.cppだった。321行目あたりにmainあるけどこれじゃないの?
そのサイトは、mirrorサイトで「legacy」とされ、だいぶ古いバージョンなんです。
最新バージョンのソースでは、driver.cpp には clang_main()しかないと思います。
cmakeすると、buildフォルダに、
int main(int argc, char *argv[]) { return clang_main(argc, argv); }
のような一行の関数が出来ます。
- 975 :デフォルトの名無しさん:2022/10/26(水) 02:33:27.35 ID:U/bwzoe1.net
- >>974
(1) 本当の clang の main() 関数本体 :
(llvm-project-main/clang/tools/driver/driver.cpp):
int clang_main(int Argc, char **Argv) {
・・・
・・・
}
(2) clang_main() を呼び出す main() 関数 :
(llvm-project-main/build/tools/clang/tools/driver/clang-driver.cpp):
↑
build は、cmake の destination ディレクトリです。
int clang_main(int argc, char **argv);
int main(int argc, char **argv) { return clang_main(argc, argv); }
↑本当にこんな風に一行の関数になっています。恐らく、cmake が
生成したものと思われます。
- 976 :デフォルトの名無しさん:2022/10/26(水) 09:07:24.21 ID:AzbtQsoy.net
- >>974-975
なるほどすまんかった。
たまたま古いソースをみてたからmainを見つけられたんだね。勉強になりました。
- 977 :デフォルトの名無しさん:2022/10/26(水) 09:39:06.48 ID:8n8wOLOb.net
- >>964
やはりrequiresを1行足すしかないか...
template<allow_ref<std::integral> T>
void func(T&&);
とでも書きたかったけど、コンセプトを受け取るテンプレートが書けないっぽいから諦めた
- 978 :デフォルトの名無しさん:2022/10/27(木) 02:01:40.47 ID:XIiqnbUh.net
- clangのソースで、CPUのマシン語を生成している場所を調べていて、
X86AsmPrinter クラスや X86MCInstLower クラスがそれに強く関与していることが分かって
きました。
X86AsmPrinter クラスや X86MCInstLower クラスは、お互いに参照されてますが、
この2つのクラスは、いずれも「作られている場所」が見つかりません。
「作られている」とは、new X86AsmPrinter や、X86AsmPrinter a;、
new X86MCInstLower や X86MCInstLower b; のようにしている場所です。
どなたか分かりませんか?
- 979 :デフォルトの名無しさん:2022/10/27(木) 02:32:01.95 ID:XIiqnbUh.net
- >>978
すみません、多分、以下の部分ですね。
これで、new X86AsmPrinterしたアドレスを、getTheX86_32Target()やgetTheX86_64Target()
が返した Target クラスのシングルトンのインスタンス xxx に対して
xxx.AsmPrinterCtorFn = アドレス;
のように記録しているようです。
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeX86AsmPrinter() {
RegisterAsmPrinter<X86AsmPrinter> X(getTheX86_32Target());
RegisterAsmPrinter<X86AsmPrinter> Y(getTheX86_64Target());
}
template <class AsmPrinterImpl> struct RegisterAsmPrinter {
RegisterAsmPrinter(Target &T) {
TargetRegistry::RegisterAsmPrinter(T, &Allocator);
}
private:
static AsmPrinter *Allocator(TargetMachine &TM,
std::unique_ptr<MCStreamer> &&Streamer) {
return new AsmPrinterImpl(TM, std::move(Streamer));
}
};
/// TargetRegistry - Generic interface to target specific features.
struct TargetRegistry {
・・・
static void RegisterAsmPrinter(Target &T, Target::AsmPrinterCtorTy Fn) {
T.AsmPrinterCtorFn = Fn;
}
・・・
};
- 980 :デフォルトの名無しさん:2022/10/27(木) 02:43:40.35 ID:InDGsMhW.net
- なんかコンセプト以前にテンプレートにもあまり慣れてなさそう
- 981 :デフォルトの名無しさん:2022/10/27(木) 02:44:18.56 ID:XIiqnbUh.net
- 間違えました。
xxx.AsmPrinterCtorFn に登録しているのは、new X86AsmPrinterの
アドレスではなく、
RegisterAsmPrinter<X86AsmPrinter>::Allocator(・・・)
のアドレスのようですね。
そして、このAllocator (==関数)を呼び出すと、new X86AsmPrinter
を行なえるようです。
- 982 :デフォルトの名無しさん:2022/10/27(木) 08:37:49.38 ID:yP/aIJbf.net
- 関係ないけどあんまりnewせんほうがええよ
それしかないと思ってるならちょっと古い感じ
- 983 :デフォルトの名無しさん:2022/10/27(木) 22:03:08.74 ID:+UGgATct.net
- あんまりデータメンバに直アクセスしないほうがええよ
あんまりグローバル変数使わんほうがええよ
あんまりSendMessageを直に使わんほうがええよ
あんまりナマポ使わんほうがええよ
あんまりアセンブラ使わんほうがええよ
あんまりC++使わんほうがええよ
ラップしろってことだろうけど
一切離れたやつはもうC++使いじゃない
- 984 :デフォルトの名無しさん:2022/10/28(金) 00:40:37.68 ID:sQHy7sst.net
- >>982
イリノイ大学のclangやLLVMの開発者に言ってください。
コンパイラでは最先端かも知れませんが。
- 985 :デフォルトの名無しさん:2022/10/28(金) 08:56:31.64 ID:+oOKe7Yr.net
- 可変長テンプレートはじみて使ったけど便利だなこれ
- 986 :デフォルトの名無しさん:2022/10/28(金) 09:06:12.57 ID:kPJo8naK.net
- threadがあんなに使いやすくなっているのは
ひとえにtemplate-parameter-packのおかげ
- 987 :デフォルトの名無しさん:2022/10/29(土) 23:34:49.08 ID:Ank2ZEY0.net
- >>946の話は終わりかな?
レスついたけど反論がないようだけど
- 988 :デフォルトの名無しさん:2022/10/30(日) 03:51:06.75 ID:i1fpLCEI.net
- 5ch始めたばかりなのかな?
- 989 :デフォルトの名無しさん:2022/10/30(日) 11:42:15.05 ID:/mJPvv5N.net
- 気になるじゃん
- 990 :デフォルトの名無しさん:2022/10/30(日) 15:52:08.41 ID:zpZIwFpu.net
- 仕事ハネた後のヨレヨレ状態で見てるから
長文()を読もうとすると寝落ちしかねない
- 991 :デフォルトの名無しさん:2022/10/31(月) 13:27:29.89 ID:Q1JWQuIa.net
- VC++ や GCC で <cstddef> をインクルードすると、
std の明⽰的修飾、using 宣言、using 指令がなくても
size_t が使えるのですが、これは C++ 標準の仕様ですか?
- 992 :はちみつ餃子 :2022/10/31(月) 13:53:23.25 ID:HpV/6ZOj.net
- >>991
いいえ。 未規定です。
std 名前空間内で定義されることは当然に保証された動作ですが、
グローバルには定義されてもされなくてもかまいません。
逆に言えばグローバルに定義されていることはありうると想定する必要があります。
(なので自分が定義する名前がそれに衝突しないようにするべきです。)
- 993 :デフォルトの名無しさん:2022/10/31(月) 13:55:26.92 ID:cQbFxG4K.net
- size_tを知らんでもsizeofは使える?
- 994 :はちみつ餃子 :2022/10/31(月) 14:17:38.34 ID:HpV/6ZOj.net
- >>992 の根拠
https://timsong-cpp.github.io/cppwp/n3337/headers#4
- 995 :デフォルトの名無しさん:2022/10/31(月) 14:31:14.54 ID:J5sgTSch.net
- C++相談室 part162
https://mevius.5ch.net/test/read.cgi/tech/1667194175/
- 996 :デフォルトの名無しさん:2022/10/31(月) 14:31:53.89 ID:J5sgTSch.net
- 立てました
- 997 :2ch.net投稿限界:Over 1000 Thread
- 2ch.netからのレス数が1000に到達しました。
総レス数 997
290 KB
掲示板に戻る
全部
前100
次100
最新50
read.cgi ver 2014.07.20.01.SC 2014/07/20 D ★