«

""


[C++] 実行環境の差異によるintワーニングが出ない書き方

C++のワーニングを放置していたのですが、そっと @srz_zumix さんが教えてくれてました

忘れないうちに”φ(・ェ・o)~メモメモ


x86環境とx64環境が混在してる場合にエラーが出やすい

こんなやつとか出ます…

1
2
3
4
5
6
// Warning が出る例
std::vector<int> my_vec = { 0, 42 };
uint32_t max_loop_counter = my_vec.size();  // ←ここね
uint32_t counter = 0;

// 以下、counter を max_loop_counter までなんらかの処理

これは x86環境だと warning は出ないのですが x64 環境想定でコンパイルすると、ワーニングが出ます

(Clangの例)
warning: Implicit conversion loses integer precision: ‘std::__1::vector >::size_type’ (aka ‘unsigned long’) to ‘u_int32_t’ (aka ‘unsigned int’) [-Wshorten-64-to-32]

( ̄□ ̄;
ええ、ええ、判っていますとも…
int 型が処理系によって異なるのは…

そこで、やっつけで修正するならこれ

1
2
// ベタにワーニングを取ろうとするとこんな感じ
uint32_t max_loop_counter = static_cast<uint32_t>(my_vec.size());

なのですが、もっとスマートは方法があります

1
2
3
4
// 今っぽい感じに
std::vector<int> my_vec = { 0, 42 };
auto max_loop_counter = my_vec.size();
decltype(max_loop_counter) counter = 0;

エレガントになりました…!素晴らしい(^^♪

警告のコンパイラー対応表がある

@srz_zumix さんが最近始められたプロジェクトらしいです

ワーニング対応表欲しいな…と思っていたところなので、結構良いかもしれない…

そして今日もC++修練は続く…


[c++] 2次元配列的な書き方

自分メモ

2次元配列

C++11 以前では、2次元配列はこんな感じで書いていました

1
2
3
4
5
6
// 2-dimensional array (raw type)
constexpr static float xy_raw[][2] = {
      { 0.f,  10.f}  // 0
    , { 20.f, 30.f}  // 1
    , { 40.f, 50.f}  // 2
};

これでも悪くは無いのですが、生配列を扱うと範囲外アクセスに気が付かない可能性が出てきます そこで C++11 から境界チェックが出来る配列の std::array が登場しました
これを使えば、C-styleの配列のノリで扱うことが可能です

さらに2次元配列にしたければ std::arraystd::vector に入れることで実現可能です

1
2
3
4
5
6
// 2-dimensional array (using stl)
const std::vector<std::array<float, 2>> xy_array = {
      { 0.f,  10.f}  // 0
    , { 20.f, 30.f}  // 1
    , { 40.f, 50.f}  // 2
};

悪くなさそう

動作確認

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
#include <vector>
#include <array>

int main() {
  // ---------------------------------
  // 2-dimensional array (raw type)
  constexpr static float xy_raw[][2] = {
        { 0.f,  10.f}  // 0
      , { 20.f, 30.f}  // 1
      , { 40.f, 50.f}  // 2
  };

  std::cout << "xy_raw[0][1]: " << xy_raw[0][1] <<  "\n"; // 10

  // xy_raw[1][2] は out of rangeだけど warningになってる
  // これはたまたま xy_raw[2][0] と同じなので動作しているだけ
  std::cout << "xy_raw[1][2]: " << xy_raw[1][2] <<  "\n"; // 40

  // ---------------------------------
  // 2-dimensional array (using stl)
  const std::vector<std::array<float, 2>> xy_array = {
        { 0.f,  10.f}  // 0
      , { 20.f, 30.f}  // 1
      , { 40.f, 50.f}  // 2
  };

  std::cout << "xy_array[2][0]: " << xy_array.at(2).at(0) <<  "\n";  //40  

  // compile error
  //std::cout << "xy_array[1][2]: " << xy_array.at(1).at(2) <<  "\n";  // out of range accsess
}

結果

xy_raw[0][1]: 10
xy_raw[1][2]: 40
xy_array[2][0]: 40

コンパイル時に教えてくれるので助かります

参考


[C++] std::optionalの使い方を紹介しました

少し前ですが、std::optional について nakameguro_feature.cpp vol.13 で発表したので、その資料を置いときます

私的感想としては、optional を使うと
値取得に失敗しても、例外を書くことなく if で処理出来る のが、なんだか良いなぁと思った次第でした

あと、optional の無効状態をどう表すか?
reset() / std::nullopt / {} のどれよ?
という話は、参加者の人たちの意見も GitHub の検索結果と同じで
reset() に軍配があがっていました(‘ω’)

こういう意見交換の場は、本当に恵まれてるなぁ~しみじみ

次回は 3 / 28 (木)開催で、vol.18 です!

お時間ある方は、ぜひお立ち寄りください~!


[Android] 謎のエラー「Unable to start debugging.」が出たときの対応

Androidデバッグで実行時エラー

環境

ある時…Visual Studio で作っている Android プロジェクトが、実行時エラーになりました

Unable to start debugging. Check your debugger settings by opening project properties and navigating to ‘Configuration Properties–> Debugging’

デバック出来ないからね!プロジェクトの設定見てね!的な意味みたいですが
デバッグモードで動かしてるし…
一体どこの何の事を言ってるのか判らない…><。

リリースモードならOKなのかしら?と思っても、同様のエラー”(-“”-)”

解決案(わたしはこれでは解決しませんでしたが)

検索しても、実のある回答は特に出てこず…
唯一、解決っぽいのが、NVIDIAさんのフォーラムに載ってました

元ネタリンクはMicrosoftさんのGitHub情報みたいです

簡単に言うと、VSの Developer Command Prompt を使って、キャッシュクリアしてみたら?というもの
やってみました

  1. Developer Command Prompt を検索して立ち上げる

  2. 以下のコマンドを打つ

Devenv /UpdateConfiguration
Devenv /ClearCache

もっともらしい対策なんですけど、わたしの実行時エラーは解決しませんでした
何がダメなのだろ…((+_+))

わたしが解決した方法

で、実際の解決策ですが…
すみません、散々あーだこーだ書いてますが
スタートアッププロジェクトの設定もれ でした…( ;∀;)
いやはや、お恥ずかしい…

Androidプロジェクトが参照する、別のプロジェクト達が
同じソリューションファイルの中に複数存在しています

なのに、Androidプロジェクトを起動プロジェクトに設定しておらず…

ポカミスとはまさにこの事!( ;∀;)

なぜこれに気が付かなかったのか…相当焦ってて、周りが見えてなかったみたいです

二度と同じ過ちを繰り返さないように…><。
あと、同様のエラーで困ってる人の何かしらの参考になればと思います><。


[C++] VisualStusio2015でClangを使う設定

今日は Clang with Microsoft CodeGen の設定などについて、メモしておきます

先人たちが既に色々と試している内容と対して変わりませんが、そもそも日本語の情報も少ないので、何かの足しになればと思います

“Clang with Microsoft CodeGen” is here!

最近はすっかり、クロスプラットフォームやオープンソースに力を入れているマイクロソフト社のツールセットの中に、Clang対応ってのがあります

2015年の年末にですが、Clang が正式に Visual Studio 2015 Update1 で利用できるよ~
とVC++チームブログで発表されていました

良いですねー(^^)
現在のVS2015には Clang with Microsoft CodeGen というツールセットが提供されており、目玉はなんといっても、Clang のデバックを Visual Studioのエディターで確認できるところでしょうか!

他にも、Clang でコンパイルしたobjと VC でコンパイルしたobjがリンクできるところもすごいです
既存資産をフル活用出来そうですね

(2016/5/15現在、Visual Studio 2015 Update2 が最新です)
https://www.visualstudio.com/ja-jp/news/vs2015-update2-vs.aspx


LLVM側にも記事が上がっています


日本でも既に先人が試されているので、読んでみると良いと思います


ちなみに、この Clang with Microsoft CodeGen は VC++チームブログにも “a.k.a. Clang/C2” と記載されており、別名を Clang/C2 というようです

また、今回対応している Clang 側のバージョンは 3.7 です

clang.exe の場所

Clang

1
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\Clang 3.7\bin\x86\clang.exe

ちなみにVC++

1
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\cl.exe

どちらでも、コマンドプロンプトでコンパイル可能です

VSでのコンパイラの切り替え設定

Visual Stidon 2015 上で “Alt + F7” を押すか

プロジェクト > [プロジェクト名]のプロパティ

で設定UIを表示させます

構成プロパティ > 全般 > プラットフォームツールセット

この項目を “Clang 3.7 with Microsoft CodeGen (v140_clang_3_7)” に変更するだけです

結構簡単\(^o^)/

ソリューション作成は何でもOK

上記の様に、コンパイラが簡単に切り替えられるので、空のプロジェクトでも、Win32コンソールアプリケーションでもOKです

一応、Clangっぽいプロジェクトはあるんですけど、いきなり dll というのもなんだか敷居が高いので、

exe を作りたいだけなら、Win32コンソールアプリケーションで良いと思います

[余談]文字コードはUTF8の方が良い(様な気がする)

最初に書いておくと、Sift-JIS でも Clang/C2 でコンパイルは通ります

…なのですが、一応、なんとなく

個々の環境によって異なるのかもしれませんが
わたしがVS2015で作成した cpp ファイルは、デフォルトで Sift-JIS になります

既に、VC++チームブログ にはこんな感じで↓↓↓

If source files in the project you are trying to convert are UTF-16 encoded, you will need to resave them as UTF-8 when Clang gives you an error about UTF-16 encoded source with BOM.

UTF-16はだめらしいです
Sift-JIS は無関係かもしれませんが、一応…

サンプルコード

cpprefjp を参照して、サンプルコードを書いてみました

VC2015 Update2 では未対応だけど、Clang 3.7 は対応しているというコードです

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#include "stdafx.h"
#include <iostream>

constexpr int f()
{
	int result = 0;
	return result;
}

int main()
{
	std::cout << "Hello: " << f() << std::endl;

	return 0;
}

Visual Studio 2015 (v140) でコンパイルすると、エラー

VS2015 ではまだ、constexpr関数内の変数宣言がエラーになる様です

Clang 3.7 with Microsoft CodeGen (v140_clang_3_7) でのコンパイル

Clang はOKです
いい感じに動作しました!


VC++も Clang も、VS上でデバック出来るのは良いですね
噂には聞いていましたが、自分で動作させてみると、感激するもんがあります

今はまだプレビューらしいので、早く安定化して欲しいですね~


[勉強会] ebisu_effective_modern.cpp vol.3やりますよ

ebisu_effective_modern.cppって?

東京の恵比寿でC++について、みんなの意見を聞きながら本を読み進める勉強会を開いています

昔、大阪でC++の読書会を開催していたのですが、それが結構役に立って面白かったので、東京でも開催してみよう!と思い、始めてみました

ネタが無いと勉強や会話もしずらいので、
「Effective Modern C ーC11/14プログラムを進化させる42項目」 を元に進めています

今回は、5章 右辺値参照、ムーブセマンティックス、完全転送 について…
前回の vol.2 では、基本的なムーブの動きを簡単に抑えた程度になったので、あまり深いところまでは進めませんでした
書籍の内容にぐいぐい追いつけるように頑張りますよ~

興味ある方はどうぞ、お気軽にお越しください(^^)/


[C++11] 参考リンク情報

C++11について調べているときに参考になった情報源のメモ

VS2013とVS2015 previewで利用できる機能一覧が乗っている


[C++/CX] MVP Community Camp 2014大阪で「VC++まわりの非同期処理」セッションしました

MVP Community Camp 2014大阪にて、VC++系のセッションをさせて頂きました

MVP Community Camp 2014大阪会場
http://atnd.org/event/E0024087 (リンク先は削除されている模様です)

当日利用した資料はこちら!


 pptx版はこちら  ←セッション時の私的メモが欄外に載っています
 PDF版はこちら

序盤はわたしの追体験発表みたいになってしまいました
同じような疑問を持っている人や、その人なりの解釈の手助けになる様であればと思って記載しています

後半部分は、VC++での非同期処理の触りだけになっていますが
非同期での例外や中断など、C++/CXのWIndowsストアアプリでは興味深い仕組みが色々あるので
この続きになる情報も、もっと自分なりに勉強して発信していきたいなー


Anonymous Struct of C

Hi,

It is very tedious to think about the name of a struct when you use to struct only once.
In such a case, Anonymous structure comes in handy.

It is assigned to the anonymous struct

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
struct{
        char    1st_name[0x80];
        char    2nd_name[0x80];
 
    } name_tbl[] = {
        { "Isami",   "Kondou" },
        { "Toshizo", "Hijikata" },
        { "Kogorou", "Kathura" },
    };
 
    for( i = 0; i < sizeof( name_tbl ); i ++ ){
        printf( "%s\n", name_tbl[ i ].1st_name );
        printf( "%s\n", name_tbl[ i ].2nd_name );
    } 

This code is very straightforward!

This method is effective only when there is no necessity that you use 2 times and this structure.


C,C++,C++/CLI sample program

Hi,

C program

1
2
3
4
5
6
7
8
c00.c
#include <stdio.h>

int main()
{
    printf("This is a native C program.\n");
    return 0;
} 

compile

> cl.exe c00.c

C++ program

1
2
3
4
5
6
7
8
c01.cpp
#include <iostream>

int main()
{
    std::cout << "This is a native C++ program." << std::endl;
    return 0;
}

compile

> cl.exe /EHsc c01.cpp

C++/CLI program

1
2
3
4
5
c02.cpp
int main()
{
    System::Console::WriteLine("This is a Visual C++ program.");
}

compile

> cl.exe /clr c02.cpp

That is very interesting!