syghの新フラグメント置き場

プログラミングTipsやコード断片の保管場所です。お絵描きもときどき載せます。

プログラミングTips

C++における構造体のコンストラクタはユーザー定義すべきではない(私見)

C++のクラス (class) と構造体 (struct) は、デフォルトのメンバーアクセスレベルが異なるだけなので、機能的な違いはありません*1。構造体でも、メンバー変数だけでなくメンバー関数を定義することができます。当然コンストラクタやデストラクタをユーザー…

C/C++の汎整数拡張(昇格)と条件(三項)演算子

現在主流のプロセッサは、異なる型の数値同士を直接演算することはできません。必ず型を揃える必要があります。 C/C++は暗黙の型変換を許すパターンが多数ある危険な言語なんですが、中でも異なる整数型、特に符号付きと符号無しの整数型を混ぜると、暗黙的…

C/C++がクソ言語である最大の理由

C/C++には公式の言語リファレンスが存在しません。言語仕様や標準ライブラリ仕様を正確かつ明快に記述した無料の公式オンラインドキュメントが存在しないんです。 正直、これは致命的とも言えるレベルの欠陥だと思っています。これがクソ言語たる最大の理由…

MSVC (ユニバーサルCRT) のswprintfのバグ

Visual C++のC Runtime (CRT) ライブラリは、バージョン2015 (14.0) 以降、新しい設計のUniversal CRT (UCRT) を採用するようになり、C/C++標準ライブラリが再実装されました。 その際、かなりの数のバグが混入したのですが*1*2、いまだに修正されていないバ…

BSTRはwchar_tへのポインタではありません

COMの文字列にはBSTRというデータ型が使われています。 BSTRが定義されているWindows SDKのヘッダーを見てみましょう。 // <wtypes.h> in Windows SDK 8.1 #ifndef _PREFAST_ typedef /* [wire_marshal] */ OLECHAR *BSTR; #else // _PREFAST_ typedef _Null_terminate</wtypes.h>…

WindowsのOutputDebugString()関数とUnicode

WindowsのOutputDebugStringW()関数とOutputDebugStringA()関数は、デバッグコンソールに文字列を出力します。Visual Studioでデバッグ実行すると、「出力ウィンドウ」に文字列が表示されます。 ただしAndroidのLogcatや、MacのXcode+NSLogと違って、末尾に…

絶対値関数absとオーバーフロー

C/C++において、符号付き整数の絶対値を求める関数abs(), labs(), llabs()および整数型のstd::abs()関数オーバーロードには罠があり、「整数オーバーフロー」が考慮されていません。 これは、JavaやC#のような近代的な言語と違って、C/C++の整数内部表現が2…

enumの読み方・発音はイニューム

ほとんどのプログラミング言語には列挙型 (enumeration type) あるいは列挙体 (enumeration) というデータ型があり、有限集合を順序付けて定義するのに使用します。C系の言語ではキーワードenumを使用します。 /* 軍艦の種類を表す列挙型 */ typedef enum My…

ログ用に時刻を取得して文字列化する (C#, Java, POSIX/Win32)

アプリケーションのデバッグや、デプロイ後の問題解析に最も重要な役割を果たすのはログです。ログの機能や精度・粒度によって、問題解決のしやすさがほぼすべて決まります。また、ログは単なるトラブルシューティングだけでなく、場合によってはユーザー操…

Android Javaのアサーション

昨年2018年は転職したこともあって、一番よく使った言語はJavaでした。とはいっても、ほとんどはAndroidのJavaであり、サーバーサイドやデスクトップで使われている正式なJavaとはいささか性質が異なります。JavaはC/C++やC#と違ってプリプロセッサをサポー…

C++でstaticクラス

C#には「staticメンバーだけを定義して、実体化(インスタンス化)は許可しない」ようなクラスを簡潔に定義する手段があります。 public static class MyHelper { public static int Add(int x, int y) { return x + y; } } staticクラスは状態を管理しない…

Vulkanグラフィックスの簡単なレンダリングサンプル

このあいだ書いた記事「VulkanシェーダーでSub-group命令を使う」では、グラフィックスをすっ飛ばしていきなりコンピュートシェーダーで拡張命令を試すという変態的なことをしましたが、GPGPUに興味のない人には退屈な内容だったかもしれません。以前、Direc…

VulkanシェーダーでSub-group命令を使う

NVIDIAはKepler (Compute Capability 3.0) 世代のハードウェアにおいて、Warp Shuffle命令を実装しました。WarpシャッフルはCUDAから組み込み関数 (intrinsic function) の形で利用できるSIMD命令の一種で、Warpと呼ばれるスレッドグループ内での並列データ…

C/C++の#warning

コンパイルエラーを意図的に発生させる#errorプリプロセッサディレクティブに関しては、お馴染みの#includeや#defineなどと同様に言語仕様として標準化されているようで、おそらくすべてのC/C++処理系でサポートされています。 #ifdef __cplusplus #error Th…

GeForceドライバー380系列のDirect3D 11バグ

3DグラフィックスとC++の研究目的で、DirectX 11 (Direct3D 11) を使った自前FBXビューアーを開発しているのですが、とある自作FBXファイル(約18,000ポリゴン程度)を開いて、カメラを回転させながら描画すると、レンダリングが停止する現象に遭遇しました…

OpenCL/OpenGL/OpenCVのバイナリキャッシュ機能は使ってはいけない

OpenCL/OpenGLには当初、カーネルおよびシェーダープログラムに関してSPIR/SPIR-Vのような中間表現(バイトコード)規格が用意されておらず、それゆえオフラインコンパイルがサポートされていませんでしたが、コンパイル済みバイナリ(ベンダー依存)のキャ…

volatileに関してそろそろ一言いっておくか

今更言うまでもありませんが、C/C++とJava/C#ではキーワードvolatileの意味が若干異なります。 C/C++ C/C++言語のvolatile修飾子は、コンパイラに副作用を示唆し、メモリアクセスの最適化を抑制するために存在します。volatileは典型的な処理系依存機能のう…

Visual StudioのビルドイベントでPowerShellを踏み台にしてC#を使う

Visual Studioでプロジェクトをビルドする際に、複雑な前処理・後処理を記述する場合、通例バッチコマンドによるカスタマイズをします。ただ、Windowsのコマンドは貧弱で、Unix/Linux環境のシェルなどとは比べ物になりません。 従来のバッチコマンドの代わり…

Directory.Exists/File.Existsメソッドのタイムアウト時間

.NETのSystem.IO.Directory.Exists()メソッドは指定ディレクトリの存在有無をチェックするメソッドですが、タイムアウト時間が設けられています。ローカルドライブのディレクトリにアクセスする場合は、よほど低速なシステムか膨大なストレージでないかぎり…

C# 6.0コンパイラーの興味深い挙動

C#言語はnullに関連する演算子が豊富です。 null合体演算子 null合体演算子は左側オペランドがnullでない場合は左側オペランドを返し、nullの場合は右側オペランドを返します。参照型のほか、Null許容型(Nullable)にも適用可能です。C# 2.0で追加されまし…

Photoshopのレイヤー数をスクリプトで数える

本業の仕事が忙しかったこともあり、前回の記事から1年近く何も書けませんでした。すでにはてな記法を忘れつつありますが、ぼちぼち頑張ります。Photoshop内部では、レイヤーを"art layer"、グループ(フォルダーアイコン)を"layer set"と呼んでいます。 今…

Vulkan SDK付属のGLSLコンパイラー

2016年2月にVulkanの正式仕様とSDKがリリースされ、その後NVIDIAやAMDなど大手GPUベンダー各社からもPC向け正式ドライバーがリリースされ始めているので、そろそろ試してみることにしました。まずはシェーダーのコンパイラーまわりから入ります。ちなみにVul…

INIファイルでUnicodeを扱う

今更ですが今日はINIファイルのお話です。初めに断っておきますが、ぶっちゃけWindowsアプリケーションでレガシーなINIファイルを使うのはもうやめましょう。Windowsアプリケーション設定の管理には、今後はレジストリやXMLファイルなどを使うべきです。 そ…

自作MetasequoiaプラグインをGitHubで公開しました

かつて2007年~2008年頃、こっそり自分のためだけに開発したMetasequoiaプラグインのソースコードがHDDの肥やしになっていたので、Gitの練習も兼ねてGitHubに移管・オープンソース化しました。ライセンスはMITです。 GitHub - sygh-JP/SyghMQPlugins: Metase…

Visual Studio 2015とD3DCompiler

Visual Studio 2015でビルドした、DirectX 11.1を使ったMFC/WPF混合アプリ (.NET 4.5.2) をWindows 7のエクスプローラーから起動すると、起動直後に勝手に終了する現象が出ました*1。 しかし、終了時にWindowsからクラッシュエラーのタスクダイアログも表示…

XAudio2とMedia FoundationでMP3/WMA再生

経緯 以前、DirectXの学習を兼ねて開発していたゲームエンジン(C++で様々なDirectX APIを直接叩いていました)では、効果音 (SE) の再生にXACT3を、BGMの再生にDirectShowを使っていました。本当はBGMにもXACT3を使ってもよかったのですが、MP3/WMAフォーマ…

Direct3D 12 (DirectX 12) の簡単なサンプル

(本記事の内容は執筆時点の暫定仕様に基づくものです。実際の最終製品版とは一部異なる部分があります)GDCの開催された2015年3月にはすでにDirect3D 12 (DirectX 12) の暫定ドキュメントとVisual Studio 2015 CTPが公開されていたのですが、肝心の実行環境…

NVIDIAのOpenCL対応状況

NVIDIAのOpenCLドライバーはIntelやAMDと比べて規格への対応が遅く、2015年2月時点でもOpenCL 1.1どまりです。NVIDIAのOpenCL SDKとなるCUDA Toolkitも、7.0時点でOpenCL 1.1までしか対応していません(cl.hに定義されているのはCL_VERSION_1_1まで)。例え…

F#でファイル・フォルダーをごみ箱へ移動

Visual Studioのバージョン2010以降をインストールすると、拡張子.fsxにVisual Studioが関連付けられ*1、さらにコンテキストメニューに「Run with F# interactive...」というコマンドが追加されます。.fsxはF#スクリプトと呼ばれるファイルなのですが、Visua…

VS 2008のWPF-MFC相互運用

(これは2011-03-18に書いた故OCNブログの記事を移植したものです)以下を参考に、MFC アプリから WPF を使おうとして、Visual Studio 2008 SP1 のバグに遭遇しました。 WPF ユーザー コントロールを HwndSource 経由でホストする Win32 アプリ……といいつつ…