C++相談室 part136

■ このスレッドは過去ログ倉庫に格納されています
2018/06/07(木) 23:40:12.36ID:GNQuDMaA0
次スレを立てる時は本文の1行目に以下を追加して下さい。
!extend:on:vvvvv:1000:512

C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。
IDE (VC++など)などの使い方の質問はその開発環境のスレにお願いします。

前スレ
C++相談室 part135
https://mevius.5ch.net/test/read.cgi/tech/1522495206/

このスレもよろしくね。
【初心者歓迎】C/C++室 Ver.102【環境依存OK】
http://mevius.5ch.net/test/read.cgi/tech/1509780815/

■長いソースを貼るときはここへ。■
 http://codepad.org/
 https://ideone.com/

[C++ FAQ]
https://isocpp.org/wiki/faq/
http://www.bohyoh.com/CandCPP/FAQ/ (日本語)

----- テンプレ ここまで -----
VIPQ2_EXTDAT: default:vvvvv:1000:512:----: EXT was configured
2018/06/19(火) 09:20:33.15ID:1GZ30pc10
>>319
まじかよ。おまえ真顔じゃないか。
2018/06/19(火) 10:45:51.92ID:x0u1iMAyd
世の中いろんなコーディングルールがある

ifの中は副作用のあるコード禁止とか
goto禁止とか
3項演算子禁止とか
1個の関数は○○行以内とか
変数名は○○文字以内とか

実際に業務で書かない人が決めたりするからたちが悪い
2018/06/19(火) 11:00:52.67ID:2U1bfNZa0
if の条件式の中で代入することは勧められない書き方だと思うけど、
「言語仕様に照らして完全に正しいけど間違いやすい書き方」にいちいち警告を出されるとうんざりする。
オプションで強めのチェックにしたときならともかく、デフォルトでだぞ。

かといって個別に警告の有効・無効のオプションを書くのも面倒くさいしなぁ。
323デフォルトの名無しさん (ブーイモ MM6d-nvpi)
垢版 |
2018/06/19(火) 14:29:42.98ID:mTWnJSOLM
俺も定数との比較なら
if ( 0 == buf )
って定数を左に書くようにしてる
理由は>>310と同じ意図しない代入防止
324デフォルトの名無しさん (ワッチョイ 99b3-Cu4h)
垢版 |
2018/06/19(火) 15:21:42.83ID:eYArWI+v0
テスト書けば防げるよ。
325デフォルトの名無しさん
垢版 |
2018/06/19(火) 17:52:06.99
自動的に静的チェックツールかけとけば教えてくれるよ
2018/06/19(火) 18:32:24.93ID:QaAZlBtz0
関数の戻り値を保存した一時変数を使わなかっただけで警告出されるのは地味につらい。かといって警告を抑止するのも悩ましい。
以下のような感じ。

void test()
{
int foo = bar();
return;
}
2018/06/19(火) 18:38:40.93ID:+lctr4fi0
コメントアウトしておくべし
2018/06/19(火) 18:41:58.17ID:+lctr4fi0
じゃなくて・・・、BARのreturnにブレークポイントだ。
VSのばあいだけど。
そんな出口の多い構造で大丈夫か。
2018/06/19(火) 19:08:38.86ID:SpwZyN6M0
よくわからんのだが使わんものをなんで残しとくのん?
2018/06/19(火) 19:13:07.65ID:qQKHLYhfM
>>326
戻り値ありということは普通は副作用なく作るだろ
その戻り値を無視したら計算資源だけ使って何もしないってことだよ
なんのためのコードなのそれ?
2018/06/19(火) 19:42:43.55ID:B+3+LOal0
副作用の試験モジュール
2018/06/19(火) 20:12:16.04ID:j1n9w5rn0
副作用ありの関数で成功失敗その他を戻り値で返すのはごく普通にあることでは。
2018/06/19(火) 20:16:56.98ID:1co3DhsP0
だな
2018/06/19(火) 20:18:42.19ID:1co3DhsP0
>>328
barのソースが無いのかも
2018/06/19(火) 20:25:15.24ID:QaAZlBtz0
このスレは、「風邪をひいたんだがどうしたらいい?」との相談に「風邪をひくな」と真顔で回答する良スレですね。
2018/06/19(火) 20:51:33.23ID:QaAZlBtz0
相談する時は、「なんでそんなところ行ったんだ」などと“そもそも論”を始めて責任所在の確定に情熱を傾ける後ろ向きで生産性ゼロの人に相談することは避けなければならない。
これが私の設問の真意。以下が回答。

C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\ItemTemplates\VC\Windows Store\1041\BasicPage\BasicPage.xaml.cpp:97
(void) sender; // 未使用のパラメーター
2018/06/19(火) 21:00:15.56ID:QGodAC8c0
>>321
同感
2018/06/19(火) 21:00:53.62ID:EaS+ZlKPd
Visual Studioなら不要な警告を非表示に出来るだろ
2018/06/19(火) 21:02:21.72ID:ZV1HIBvv0
>>324
if (buf = 0) {
}
を検出するためのテストってどんなものですか?
2018/06/19(火) 21:03:09.63ID:QaAZlBtz0
補足すると、マクロ定義によって戻り値が使われなくなることがある場合の警告を想定。
>>336 であげた BasicPage.xaml.cppの事例は厳密には関数の仮引数を使わない場合の警告なので若干違うが、対処法は同じ。

#define OUTPUT(x)

void test()
{
int foo = bar();
OUTPUT(foo);
(void)foo;
return;
}
2018/06/19(火) 21:04:45.12ID:EaS+ZlKPd
性的解析ツールだな
342デフォルトの名無しさん (ワッチョイ 99b3-Cu4h)
垢版 |
2018/06/19(火) 21:12:21.11ID:eYArWI+v0
>>339
そのコードにエフェクトがあるならテストできるのではないでしょうか。
343デフォルトの名無しさん
垢版 |
2018/06/19(火) 21:18:56.08
>>339
そういうのはコンパイル時にWarning出るから本線にマージする前には見つかるでしょ
2018/06/19(火) 21:20:27.84ID:r5hOFOzd0
変数で戻り値を受けとって使わないって言うのは確かに変だが
戻り値がある関数の戻り値を受けとらないって言うのは問題無いのか?
2018/06/19(火) 21:25:30.71ID:ZV1HIBvv0
>>342
>>339 に対する具体的なテストの方法を示してください
2018/06/19(火) 21:29:13.02ID:bLc4VOsi0
>>345
それ単体テストやればカバレージ100%にならないから容易に検出できるだろ
2018/06/19(火) 21:38:33.29ID:SpwZyN6M0
>>340
最初に書いとけよタコが
お前の想定など知るか
2018/06/19(火) 21:42:40.31ID:j1n9w5rn0
>>339
if (buf = 0) { A }

・buf がゼロの時 A が実行されないと実行結果(出力など)が正しい結果にならない場合
・bufが非ゼロでここでゼロにされると以下同文

この2つの場合は結果がおかしいからテストで見つかる。
結果は正しいが見つけにくいリークが発生するとか
ここ間違えても結果は(常にではないが)多くの場合正しい
とかだと静的/動的カバレッジで見るしかないね。
2018/06/19(火) 21:43:57.04ID:EaS+ZlKPd
俺の中のうざい警告

使わない引数、変数、関数の警告
セキュリティ関連
演算にカッコを付けろという警告
350デフォルトの名無しさん
垢版 |
2018/06/19(火) 21:50:59.42
非適合コード: a = a + b + c;
適合コード: a = ( a + b ) + c;
2018/06/19(火) 21:52:07.12ID:j1n9w5rn0
>>349
>演算にカッコを付けろという警告

メンテしてるアプリのソース内のMD5だか sha だかのコード(問題なく動作中)で
「&とシフトの優先順位わかってんのか?括弧つけたら?」の警告が出るが、
&とシフトの優先順位など知る気もないし書き換えるとバグる気しかしないので放置している。
2018/06/19(火) 23:06:43.31ID:j3AUln/x0
セキュリティ警告無視する人とは仕事したくない
2018/06/19(火) 23:42:48.11ID:Ac6XacCG0
質問です
std::unique_ptrはデストラクタで保持するリソースの解放処理を行うので、自明なデストラクタを持つことが出来ず、リテラル型になることが出来ないと思うのですが
デフォルトコンストラクタとnullptrを受けるコンストラクタはconstexpr指定されています、このconstexprにはどういう意味があるのでしょうか?
2018/06/20(水) 00:16:23.94ID:ai7I58Bid
>>353
https://stackoverflow.com/questions/30766103/why-declare-constrexpr-constructors-for-classes-with-non-trivial-destructors-e/30766445#30766445
によれば
constexpr でないコンストラクタよりも先に(恐らくはコンパイル時に静的に)初期化されるので、

例えばグローバル変数
foo apple;
unique_prt<T> orange;

とあるとき
初期化順を気にせず apple のコンストラクターの中で orange を使用することが出来る。
2018/06/20(水) 01:00:54.85ID:PR6OT2JV0
>>354
リテラル型とまではいかないにしてもコンパイル時に初期化してくれるんですか、なるほど
ありがとうございます
356デフォルトの名無しさん (ワッチョイ ff9d-E6HK)
垢版 |
2018/06/21(木) 04:41:53.49ID:G2MjnjmO0
Scopeのついた#defineのような書き方ってないのでしょうか?
たとえば Uart0.baud 115200を変数としてしてじゃなくてDefineで保持しておきたい
場合にScopeを整理しておきたい。
2018/06/21(木) 07:10:33.64ID:Grok3vuS0
template<int baud> class Uart0 {
358デフォルトの名無しさん (アウアウカー Sa93-tQU5)
垢版 |
2018/06/21(木) 08:23:50.96ID:iolQTPDna
>>356
C++では#defineではなくconstを使うと習いました
2018/06/21(木) 08:30:36.61ID:L/t8iXOTM
先生!プリプロセッサで完結する処理もconstを使うのですか?
360デフォルトの名無しさん (ワッチョイ ff9d-E6HK)
垢版 |
2018/06/21(木) 08:52:37.07ID:G2MjnjmO0
Constはラムに配置されますからダメですよ。
それからTemplateは型を変数にしたい場合につかえるだけです。Scopeのついた
定数がないとすると、、、、、なんか使いにくいですね。
2018/06/21(木) 09:17:30.93ID:lqJXL95H0
enum
static const
2018/06/21(木) 10:14:08.56ID:Grok3vuS0
名前空間 にconst定数を閉じ込めて、スコープ内で using namespace xxx; を宣言して名前空間を明示せずに定数にアクセス。
2018/06/21(木) 10:38:55.31ID:7g4G/GMb0
defineをconstに書き換えるぐらいなら別の言語使いますよね。
364デフォルトの名無しさん (ワッチョイ 1f7f-GwbS)
垢版 |
2018/06/21(木) 10:43:19.88ID:1tnpfBql0
今どきdefine使ってる奴なんていたらクビだわ
2018/06/21(木) 10:55:24.84ID:7g4G/GMb0
クビにできる立場の人がソースコードチェックしてる会社なんですね。労組がないとかただの派遣屋ですね^^
2018/06/21(木) 11:52:28.73ID:pthrcCRVd
整数に関しては遥か昔から enum がスコープ付き定数として使われてただろ
2018/06/21(木) 12:34:10.47ID:Oz+pq3ApM
>>360
組み込み向けとかでROM実行になっていなければ、どちらもRAMに配置されると思うよ。
もしもコンパイル時解決するかどうかということであれば、constでもちゃんとコンパイル時解決されるし、式(含関数)の場合はconstexprキーワードを使えばコンパイル時解決(可能なら)される。
あと、templateは型だけでなく定数も置けるよ。
2018/06/21(木) 12:49:18.77ID:m6fyxFJ7d
考えるべきなのは2つ

コードの即値として使われるのか
値がある番地にマッピングされるのか
その都度関数コールで解決するのか



マッピングされる場合、どのセクションにマッピングされるのか
369デフォルトの名無しさん (ワッチョイ 9fd2-GwbS)
垢版 |
2018/06/21(木) 13:52:00.91ID:Grok3vuS0
const定数は ヘッダーファイルで宣言するだけではダメでソースファイルでconst定数の実体を初期化しなければならないので、defineより使い勝手が悪い面もある。
最新のC/C++だとその辺どうなってんの?
2018/06/21(木) 13:56:06.62ID:7g4G/GMb0
処理系依存させずソースレベルで終わらしたい。
2018/06/21(木) 13:59:26.98ID:S4IxNo+10
>>369
メンバ変数でも数値ならソース側に定義要らないから
struct SimpleMath {
const static int pi = 3;
};
でいい

実体がたくさんできるのを苦にしなければ
namespace n {
const static int pi=3;
};
でもいいし
2018/06/21(木) 14:03:31.13ID:S4IxNo+10
>>369
関連してついでに言うとよほど古いコンパイラじゃなければ

struct T {
int k=0;
};

というメンバ変数の初期化の書き方もできて
複数のコンストラクタがあるときとか楽できるよ
2018/06/21(木) 14:33:40.53ID:m6fyxFJ7d
>>371
ゆとり乙
2018/06/21(木) 15:05:26.80ID:JKhrQo7xd
>>326
(void)bar()
2018/06/21(木) 15:15:08.56ID:m6fyxFJ7d
>>340
2018/06/21(木) 16:24:46.01ID:n4WYHGZ/0
実体が沢山出来るとか馬鹿かテメーは
それが事実ならリンク時にエラー大量発生しとるわ
2018/06/21(木) 16:39:35.71ID:S4IxNo+10
>>376
人をバカにしたい意識が強すぎるから static 変数は
外部リンケージを持たないなんて基本も忘れるんだよ。
2018/06/21(木) 16:40:51.05ID:S4IxNo+10
ほら試してやったぞ
アドレスが違うから2個あるのがわかるだろ?

MacBook-Pro:tmp$ cat a.h
namespace a {
static const int b = 8;
};

MacBook-Pro:tmp$ cat a0.cpp
#include <cstdio>
#include "a.h"
extern void foo();
int main() {
foo();
printf("main %lx\n", (long) &a::b);
}

MacBook-Pro:tmp$ cat a1.cpp
#include <cstdio>
#include "a.h"
void foo() {
printf("foo %lx\n", (long) &a::b);
}

MacBook-Pro:tmp$ c++ a0.cpp a1.cpp
MacBook-Pro:tmp$ ./a.out
foo 10925bfb0
main 10925bfac
2018/06/21(木) 16:46:33.44ID:7g4G/GMb0
マカーのくせにC++使ってんじゃねぇ。
2018/06/21(木) 16:50:45.19ID:S4IxNo+10
ソース中で(アドレスは使われず)値しか用いられなければ実体が全く作られない可能性もあるが
オブジェクトファイル見なきゃ確認できなくて面倒だからそれは略
2018/06/21(木) 16:58:48.07ID:kxxiYbMo0
クラステンプレートにしておけば (そして型引数が同じであれば) リンクのときにインスタンスが統合されるので、それを利用できるかもね。
2018/06/21(木) 17:00:11.80ID:S4IxNo+10
>>381
クラス使うなら普通に>>371の上の方で良いかと思う
2018/06/21(木) 17:07:19.43ID:n4WYHGZ/0
>>377
だからよう、なんでstatic付ける必要あるんだよ
付けなければ実体一つで済むだろ馬鹿かテメーは
2018/06/21(木) 17:27:13.58ID:S4IxNo+10
>>383
付けなかったらリンクエラー出るだろ

こういうとお前はバカだからヘッダーでは extern しておいて
どっかのソースに1つ実体を書けとか言い出すんだろうけど、
もともと>>371>>369の「ヘッダーだけで済ませたい」への返事だからな。

まだ他に言いたいことがあるなら日記に書け
2018/06/21(木) 17:36:33.91ID:n4WYHGZ/0
>>384
出ねぇよ馬鹿かテメーは変数と扱い違ぇんだよ
2018/06/21(木) 17:49:19.83ID:m6fyxFJ7d
#defineが一番確実
最適化も一番期待できるしCとの互換性も保てる
ってことでいまだに#defineは使う
スコープ問題は昔ながらのプレフィックスで解決

小さな組み込みマイコンだと
C++でもこんな感じ
2018/06/21(木) 17:54:20.05ID:z6qVeoOj0
と、クソ雑魚老害がさえずってます
せめてenumにしろよ雑魚
388デフォルトの名無しさん (ワッチョイ 1fb3-RzAk)
垢版 |
2018/06/21(木) 17:54:46.47ID:RX0X5VqW0
フリースタンディング環境の話をこっそり忍ばせてくる技の名前なんだったっけ。
2018/06/21(木) 18:03:41.90ID:m6fyxFJ7d
逆に値を変えても1バイトしか変わって欲しくないときや
1バイトを無理やり変えると動作が正しく変わってほしいとき
は番地に割り当てられるようにする

PCプログラムしか書いたことがない人は気にしたことも無いだろうけど
2018/06/21(木) 18:09:49.54ID:Mgrb3Kbk0
#defineアレルギー
gotoアレルギー
printfアレルギー

この板には多い
2018/06/21(木) 18:59:05.50ID:bCLvNhPr0
mainと言う文字列見ると、猛烈に指先がかゆくなる
2018/06/21(木) 19:10:53.21ID:pTjgD9kkM
WinMain
2018/06/21(木) 20:50:48.63ID:z6qVeoOj0
_tmain
2018/06/21(木) 23:04:20.73ID:7g4G/GMb0
もはやドライバ書くときしかC++使わないし、最近のC++機能は全部いらね
老害とか言ってる奴の用途なんて元々、JavaやC#で十分だろ
2018/06/22(金) 00:11:53.23ID:SAq8bqNQa
内容あまり理解してないがconstexprは論外なのか
2018/06/22(金) 00:24:42.97ID:JUnpVDzH0
定数意外の計算(変数なんかが含まれる)とコンパイルエラーになる。
2018/06/22(金) 00:28:24.33ID:JUnpVDzH0
constexprは関数が返す内容が定数であることを保証する
コンパイル時はインラインでその関数を走らせて順次定数に置き換えてコンパイルが行われるということだ
2018/06/22(金) 00:31:25.00ID:/HdPI0MA0
コンパイル時定数ということですよな
2018/06/22(金) 00:33:52.46ID:SAq8bqNQa
constexprは変数も定義可能だから今回の内容なら名前空間にconstexpr変数を定義すればokかなと思ってたり...
2018/06/22(金) 00:34:25.67ID:JUnpVDzH0
まあそういうこったな
どんだけ糞長い関数書こうとその関数を呼び出した時点で定数に置換されてコンパイルされる
2018/06/22(金) 00:47:02.44ID:bQfSOVA40
>>396
それc++11
2018/06/22(金) 01:46:46.25ID:Hssdw/9K0
constexprだけど計算にとても時間がかかる場合はどうなるんだろう

延々とコンパイルが終わらないとかエラーになるとか勝手に実行時解決になるとか?
403デフォルトの名無しさん (ワッチョイ 1fb3-RzAk)
垢版 |
2018/06/22(金) 03:26:28.59ID:0qBHNE4T0
constexprで学習した結果のみ実行時に用いるAI。
404デフォルトの名無しさん (ワッチョイ ff9d-E6HK)
垢版 |
2018/06/22(金) 03:36:59.17ID:1CqwlerO0
結論が出たようなのでまとめる
1.#defineは欠点が多い。スコープが効かないのでC++では基本的に使わないこと。
2.代わりにconstexprを使う。constexprは、汎用的に定数式を表現するための機能である。
constexprは、「constant expression (定数式)」の略語である。

例1
#define BIT(n) (1<<n)
これは汎用性が高いので書き換える必要はないようにも思えるが、正しくは
constexpr int BIT(int n){ return 1 << n; }
このように書かなければならない。

例2
#define UART_A0_baud (115200)
#define UART_A0_stop (1)
#define UART_A0_bit (8)
#define UART_A0_parity (0)
#define UART_A1_baud (9600)
#define UART_A1_stop (2)
#define UART_A1_bit (8)
#define UART_A1_parity (1)
これをconstexpr を使って綺麗に書いてみよう。任せる。
2018/06/22(金) 03:50:55.40ID:2mqIozuo0
C++書けるやつはかっこいいな-
ただ俺が書こうとしてないだけだけど
2018/06/22(金) 04:53:39.22ID:6eBOmsiI0
>>404
お断り致します。
407いちるいなんがずっとだしおっかけてついてくるし (ワッチョイ 1f76-lC4z)
垢版 |
2018/06/22(金) 06:11:32.65ID:kyYAMp480
でふぁいん てんてきのしんにゅう がちょくじゃないから あんしんするじゃないかな


めいんすとりーとからいっぽんはいったほうが
408デフォルトの名無しさん (ワッチョイ 1f76-lC4z)
垢版 |
2018/06/22(金) 06:13:05.67ID:kyYAMp480

409デフォルトの名無しさん (ワッチョイ 1f76-lC4z)
垢版 |
2018/06/22(金) 06:15:15.42ID:kyYAMp480
カチグミニチカイホウガアブナイヨネここはあんぜんしゅうだんすとーかーにとっては

てんごく あんじゅうのち
410デフォルトの名無しさん (アウアウウー Sae3-E6HK)
垢版 |
2018/06/22(金) 06:44:34.82ID:1fAWv7Tna
適当
https://ideone.com/3pPDGA
411デフォルトの名無しさん (ブーイモ MM0f-mx2r)
垢版 |
2018/06/22(金) 07:48:57.63ID:jUqm4dE5M
>>402
constexprはコンパイル時評価可能(評価するとは言っていない)なのでコンパイラ依存。
コンパイル時間が伸びるのが大半だろうけど。
2018/06/22(金) 08:37:19.28ID:PS4w2oBw0
>>410
テンプレートクラスを使った変態バージョンを作ってみたわ
https://ideone.com/6i6un3
2018/06/22(金) 08:58:31.90ID:bJNd9Nrpd
>>411
確実にコンパイル時に解決されてるためには
別プログラムで計算して即値を#defineがベストって事だな
2018/06/22(金) 09:02:09.74ID:bJNd9Nrpd
>>411
「とても」ってのは例えば10年かかるとかそういうの
ある数学定数の計算とか固定データの暗号化を破るプログラムとか

適度にあきらめてくれないと
コンパイルが(事実上)出来なくなる
2018/06/22(金) 10:38:03.07ID:Hg4H5zqra
>>413 そこは即値をconstexprにしようぜ。
2018/06/22(金) 11:05:51.83ID:VkaCaqwn0
>>404
constexprならunsignedじゃなくても平気なのかな?
2018/06/22(金) 14:23:31.03ID:0acoPbmK0
>>385
リンカの挙動に付いては変数と扱いが違うせいじゃなくて
c++ では const 変数はデフォルトで static なくだけだよ

お前は正しい指摘をしている時でさえ必ず間違ったことを言う
このスレ読んでる人に嘘ついて喜んでる愉快犯か何かか
418デフォルトの名無しさん (スプッッ Sd1f-SNrP)
垢版 |
2018/06/22(金) 14:25:48.43ID:oyBTubw6d
現代においてdefineを使う利点がゼロ
2018/06/22(金) 14:31:22.11ID:JUnpVDzH0
は?constをヘッダにstaticで定義しているバカが居たことに驚きなんだが
そりゃstaticで定義しまくったら実体増えるのは当たり前だろ
灯台下暗しでstatic記述するバカに気付かなかったわ
バカ過ぎて話にならんわw
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

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