質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

3回答

1369閲覧

C++ グローバル配列の先頭アドレスをコンパイル時定数として扱いたい

bjnes

総合スコア113

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

1クリップ

投稿2020/06/25 01:15

前提・実現したいこと

C++20

下記ソースコードのようにグローバル配列の先頭アドレスをテンプレート引数として
使用する方法はないでしょうか?

組み込みで使用することを想定しています。
Linux上でもコンパイルと実行ができるようにしたいと考えています。

発生している問題・エラーメッセージ

式には定数値が必要です -- "Kernel::byte *" から "unsigned int" への変換は、定数式の評価では無効です

該当のソースコード

C++

1uint8_t MemorySpace[0xffff] ={}; 2constexpr size_t MemorySpaceAddr = reinterpret_cast<size_t>(MemorySpace); 3 4template<size_t BaseAddr,size_t,Range> 5class MyAllocater 6{ 7(中略); 8} 9 10int main() 11{ 12 MyAllocater<MemorySpaceAddr,0xffff> alc1; 13} 14 15

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

質問文のコードだとreinterpret_castを用いていますが、reinterpret_castconstexprな文脈中で用いることはできません。c++20でstd::bit_castが登場しますが、ポインタ型の場合に定数式として評価できないので代用することはできません。

一方、非型テンプレートは参照やポインタを取ることができるので、ポインタ自体をテンプレート引数にすることは可能です。ポインタの場合は外部リンケージでもおkのはずです

c++

1#include <cstdint> 2#include <iostream> 3 4std::uint8_t buffer[0xffff] = {}; 5 6template<std::uint8_t* BaseAddr, std::size_t Range> 7class MyAllocater 8{ 9public: 10 MyAllocater() { 11 *BaseAddr = 42; 12 } 13}; 14 15int main() 16{ 17 MyAllocater<buffer, 0xffff> alc1; 18 std::cout << (int)buffer[0] << std::endl; // 42 19}

bufferを別ファイルに移したバージョン

投稿2020/06/25 05:23

tyu_ru_cpp

総合スコア40

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

bjnes

2020/06/25 06:38

まさしくコレです。ありがとうございます。 外部リンケージのバッファーは好きなように後でリンクしたかったので、 大変助かりました。
guest

0

変数のアドレスはコンパイル時には確定していません。
ソースファイルのコンパイルが終わったあと、リンカによる各オブジェクトファイルのリンク、再配置作業でそのアドレスは確定します

なので、コンパイル時定数としては使用できません

ましかし、一部のツールチェインでは、コンパイル、リンクのあとに、最適化のためにその結果を持って再度コンパイルを行う、というビルドシーケンスを持つものもあるので、そういう動作を持つツールチェインを構築できるのであれば、不可能ではないでしょうね

投稿2020/06/25 04:27

y_waiwai

総合スコア87800

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

bjnes

2020/06/25 05:01

回答ありがとうございます。 おそらく無理(ものすっごく大変)なのは承知してました。 プレリンクをして、アドレスを割り出して、 再コンパイルの手順が必要そうですね。 現在、リンカ周りを調べています。
guest

0

こんにちは。

アドレスが確定するのは速くてもリンク時です。近代的なOSではロード時にやっと確定します。
なので、コンパイル時に値が決定していないと行けないテンプレート実引数に渡すことは無理と思います。

投稿2020/06/25 04:26

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

bjnes

2020/06/25 05:04

回答ありがとうございます。 一度リンクをしてみてアドレスを割り出してあげる必要がありそうですね。 リンカ周りを調べてみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問