代码之家  ›  专栏  ›  技术社区  ›  Generic Name

为指针分配内存地址

  •  -1
  • Generic Name  · 技术社区  · 6 年前

    我试图给一个指针分配一个内存地址,但无法编译它。 地址是一个内存映射的硬件寄存器。

    #include <memory>
    
    template<void* Address>
    struct ClassAImpl {
        uint64_t* Register = reinterpret_cast<uint64_t*>(Address);
    };
    
    uint8_t arrA[10] = { 1, 2, 3, 4 };
    using ClassA1 = ClassAImpl<(void*)&arrA>;       // error: the address of the 'void' subobject of 'arrA' is not a valid template argument
    using ClassA2 = ClassAImpl<0x8767876787678767>; // error: could not convert template argument '9756915996444559207' from 'long unsigned int' to 'void*'
    
    
    template<uint64_t Address>
    struct ClassBImpl {
        uint64_t* Register = reinterpret_cast<uint64_t*>(Address);
    };
    
    uint8_t arrB[10] = { 1, 2, 3, 4 };
    using ClassB1 = ClassBImpl<(void*)&arrB>;       // error: conversion from 'void*' to 'long unsigned int' in a converted constant expression       
    using ClassB2 = ClassBImpl<0x8767876787678767>; // This compiles.
    

    我想让a1类从指向缓冲区的指针,而a2类从一个固定地址。

    我用GCC 8.2编译C++

    2 回复  |  直到 6 年前
        1
  •  0
  •   Mateusz Wojtczak    6 年前

    我不知道你想达到什么目的,但你陷入了非类型模板参数的奇怪行为中。非类型模板参数不能用临时变量实例化。从 https://en.cppreference.com/w/cpp/language/template_parameters :

    “对于指向对象的指针,模板参数必须指定 具有静态存储持续时间和 链接(内部或外部)或常量表达式

    using ClassA1 = ClassAImpl<(void*)&arrA>; - temporary
    using ClassA2 = ClassAImpl<0x8767876787678767>; - template argument is constant expression, template parameter is pointer to void, doesn't make any sense
    using ClassB1 = ClassBImpl<(void*)&arrB>; - temporary
    using ClassB2 = ClassBImpl<0x8767876787678767>; - constant expression which can be used as template parameter uint64_t
    
        2
  •  0
  •   Davislor    6 年前

    也许你想要这样的东西:

    #include <stdint.h>
    
    uint64_t (&hw_regs)[10] = *reinterpret_cast<uint64_t(*)[10]>(0xdeadbeefUL);
    uint64_t &hw_reg0 = hw_regs[0];
    

    volatile 如果你需要的话。如果你在问射中自己脚的子弹口径,你知道你在做什么。剖面[表达式重新解释.cast]标准允许这种类型的转换,但当然引用不是安全的派生的。