GCC拡張モジュールをコンパイル時にチェックして、特定の関数がリテラル文字列でのみ呼び出されるようにすることもできます。
MELTを使用すると、GCCを拡張できます。 MELTは、GCCコンパイラを拡張するための高水準のドメイン固有の言語であり、必要なチェックの種類に非常に適しています。
基本的には、GCCの中に新しいパスを追加し、MELTで渡すコードは、関数の呼び出しであるすべてのジンプルを見つけ、引数が実際にリテラル文字列であることを確認します。 ex06
の例はmelt-examplesにあります。その後、[email protected]に登録してMELTに特定の質問をしてください。
もちろん、これは簡単な方法ではありません。ポインタを介して関数を間接的に呼び出すことができます。部分的なリテラル文字列を持つ。 f("hello world I am here"+(i%4))
は、概念的には、リテラル文字列(例えば、.rodata
セグメント)を含むコールですが、生成されたコードやジンプルには含まれません。
// these are used to force constant, literal strings in sqfish binding names
// which allows to store/copy just the pointer without having to manage
// allocations and memory copies
struct _literalstring
{
// these functions are just for easy usage... not needed
// the struct can be empty
bool equal(_literalstring const *other) { return !strcmp((const char *)this, (const char *)other); }
bool equal(const char *other) { return !strcmp((const char *)this, other); }
const char *str(void) { return (const char *)this; }
bool empty(void) { return *(const char *)this == 0; }
};
typedef _literalstring *LITSTR;
constexpr LITSTR operator "" _LIT(const char *s, size_t) {
return (LITSTR)s;
}
その後、あなたはこのようにあなたの関数を宣言します:
void myFunc(LITSTR str)
{
printf("%s\n", str->str());
printf("%s\n", (const char *)str);
const char *aVar = str->str();
const char *another = (const char *)str;
}
そして、あなたはこのようにそれを呼び出す:あなたが何かをした場合
myFunc("some text"_LIT);
私はこれを使用
文字列リテラル以外ではできない文字列リテラルではどうしますか?そして、文字列リテラルを使って初期化された 'const char * const'変数を渡すのはどうですか?または 'const char(&array)[]'は文字列リテラルへの参照ですか? – hvd
これは不可能です。文字列リテラルは 'char const [N]'配列なので、文字列リテラルと区別できません。 – Xeo
おそらく、このrvalue参照のときにデータを読み込み専用にする型に変換するユーザー定義の文字列リテラルを使用している(名前付き変数ではない)可能性があります。目標は、文字列がコール時にコードに文字どおり入力され、アプリケーションイメージに静的にコンパイルされるようにすることです。 –