只要我不使用它,我可以安全地创建对可能无效内存的引用吗?

Jo *_* So 8 c++

我想用C++解析UTF-8.在解析一个新字符时,我事先并不知道它是一个ASCII字节还是一个多字节字符的领导者,而且我也不知道我的输入字符串是否足够长以包含剩余的字符.

为简单起见,我想命名为下一个四个字节a,b,cd,因为我在C++中,我想用引用做到这一点.

只要在我知道访问安全之前我不访问它们,在函数开头定义这些引用是否有效?例:

void parse_utf8_character(const string s) {
    for (size_t i = 0; i < s.size();) {
        const char &a = s[i];
        const char &b = s[i + 1];
        const char &c = s[i + 2];
        const char &d = s[i + 3];

        if (is_ascii(a)) {
            i += 1;
            do_something_only_with(a);
        } else if (is_twobyte_leader(a)) {
            i += 2;
            if (is_safe_to_access_b()) {
                do_something_only_with(a, b);
            }
        }
        ...
     }
}
Run Code Online (Sandbox Code Playgroud)

上面的例子显示了我想要在语义上做什么.它没有说明我为什么要这样做,但显然真正的代码会更复杂,所以只有当我知道访问是安全的并且我需要它们时才会定义b,c,d会过于冗长.

Che*_*Alf 5

有三个需要:

  • 正式
    好,谁知道.我可以通过使用相当长的一段时间找到你,但是,那么,你也可以.或任何读者.而且它不是那个非常实用的.
    编辑:好的,抬头看看,因为你似乎不高兴我提到正式而没有为你寻找.正式地说你运气不好:
    N3280(C++ 11)§5.7/ 5 "如果指针操作数和结果都指向同一个数组对象的元素,或者指向数组对象的最后一个元素,则评估不得产生溢出; 行为是未定义的."
    这可能产生不良行为的两种情况:(1)计算超出段末尾的地址,以及(2)通过调试计算编译器知道大小的数据之外的地址检查已启用.

  • 从技术上讲
    ,只要你避免任何左值到右值的转换,你就可以了,因为如果引用是作为指针实现的,那么它就像指针一样安全,如果编译器选择将它们实现为别名,那么,这也是好.

  • 经济上
    依赖于不必要的微妙浪费你的时间,然后是其他人处理代码的时间.所以,不是一个好主意.相反,当它们保证它们所引用的名称存在时,声明名称.