登录 立即注册

找到11562个回复

老虎会游泳 5楼回复 无名啊如何理解 C/C++ 中的 指针别名(pointer alias)、restrict、const 的关系呢? (2023-01-27//)

其实无论是const,还是volatilerestrict,都是为了解决内存空间的所有权问题。

因为C/C++可以操作原始指针,所以内存空间的所有权可以在多个线程、函数、变量之间以任意方式共享和转移,导致编译器优化很容易出问题,所以才需要这些标记加以指示。

其他编程语言不能直接操作原始指针,所以内存空间的所有权是明确的,不需要这些编译器优化限定符。

当然const也有语法上的含义,表明你希望编译器帮你阻止对该变量的修改,所以其他编程语言里也存在该关键字。但是volatilerestrict在语法上没有任何含义,所以在内存空间所有权明确的编程语言中完全不存在。不能对原始指针解引用的语言都是所有权明确的,带GC的语言通常属于此类。

所谓原始指针解引用,就是类似这样的代码:

y  = * ( float * ) &i;

它在语法上提供了无限的灵活性,实际上可以用于读写任意内存地址:

int main() {
    long i = 1;
    float y = -1;
    const int x = 12306;

    // 以下代码没有语法错误,可以编译通过。

    // 读取原始指针
    y  = * ( float * ) (&i + 10086);
    y  = * ( float * ) 10086;

    // 写入原始指针
    * ( float * ) (&i + 10086) = y;
    * ( float * ) 10086 = y;

    // 写入 const 变量
    * (int *) &x = 10010;

    return 0;
}

因为这种灵活性,所以在C/C++中跟踪内存空间所有权变得不可能,于是需要对所有权进行人工标记。而constvolatilerestrict正是这样的标记。

const:我保证不写入这块内存空间。如果我通过原始指针解引用实现了写入,结果是未定义的。
restrict:我保证不把内存空间的所有权转移给其他变量(也就是创建别名)。如果我确实转移了,结果是未定义的。
volatile:我对该内存空间的使用不进行任何保证,请不要假设它可以被优化。至于到底能阻止哪些优化,由实现定义。

需要说明的是:volatile不是线程同步措施,它不能提供多核CPU间的内存一致性。想实现多线程内存一致性必须使用同步原语(比如互斥锁 mutex)。

老虎会游泳 4楼回复 无名啊如何理解 C/C++ 中的 指针别名(pointer alias)、restrict、const 的关系呢? (2023-01-27//)

一个指针经 restrict 修饰后,它(可能经过指针运算后)指向的对象不会不能有其它别名。

并非不会,而是不能

不会意味着编译器会阻止你为它创建别名,创建别名会导致编译错误。

但实际上只是不能,创建别名最多产生警告,程序还是能运行,而且还可能完全无错(因为编译器优化后程序出问题只是概率事件)。

所以,restrict体现的是你的自信,你得首先保证你的代码没有对该变量创建别名,然后才能给它加上restrict

就像volatile,是你不自信,觉得优化这个变量会出问题,才给它加上volatile。至于不加会不会出问题,得具体问题具体分析。

老虎会游泳 2楼回复 无名啊如何理解 C/C++ 中的 指针别名(pointer alias)、restrict、const 的关系呢? (2023-01-27//)

@无名啊volatilerestrict是编译器优化指示标记,其中volatile阻止对该标识符进行优化,restrict建议编译器对该标识符进行优化。

volatile的语义:小心,这个变量的用途很复杂,优化这个变量很可能会导致程序出问题!

restrict的语义:我保证我只通过这个变量访问它指向的内存区域,你随便优化它,绝对不会出问题!

这些都只是给编译器的提示,编译器不一定会遵循指示。比如,使用-O0编译时,加不加volatilerestrict参数都没有任何区别。只有-O1-O2-O3等有区别。

对于VC++编译器,Debug模式应该体现不出区别,只有Release模式才有区别。

const与它们不一样,它不仅是编译器优化指示标记,还进行了语法上的限制。如果不通过强制类型转换去除const标记,则无法对变量进行写入。

不过,因为const也是编译器优化指示标记,它的语义是:我保证不会对该变量进行写入,你放心优化。所以如果后续通过强制类型转换去掉const并写入变量,则Release版程序可能会出问题。注意只是可能,编译器会尽量给出不出问题的代码,所以真想遇到问题也需要碰运气。

无名啊 1楼回复 无名啊如何理解 C/C++ 中的 指针别名(pointer alias)、restrict、const 的关系呢? (2023-01-26//)

先 @ 万能的 @老虎会游泳

老虎会游泳 24楼回复 ysyvsllinux上古卷轴5怎么安装mod? (2023-01-26//)

已经添加了一个Vortex模组管理器,亲测可以正常安装mod

https://winegame.net/games/vortex-mod-manager/

ysyvsl 23楼回复 ysyvsllinux上古卷轴5怎么安装mod? (2023-01-26//)
层主 @ysyvsl 于 2023-01-26 17:48 删除了该楼层。
乄杺 4楼回复 乄杺谁能帮忙下个apk。。。 (2023-01-26//)
I Am What I Am
@𪠽,谢啦,,这个搜索引擎搜不到,,,

我手机版本也老,5.1系统,即使Android 9以上系统,我记得也是能用的,,

一样的讨厌黑暗,但是我选择了去成为一道光
hik 4楼回复 张小强有什么方式可以将web页面封装成apk (2023-01-25//)
webcat
童真再见 3楼回复 张小强有什么方式可以将web页面封装成apk (2023-01-25//)

用APP封装的容易闪退
手机

希望自己长胖胖 1楼回复 希望自己长胖胖Fedora系统为何不自带gnome-tweaks (2023-01-25//)

这回,不用为Linux命令发愁了吧

Python爱好者社区 2023-01-24 15:00
最近很多小伙伴找我要一些 Linux 基础资料,于是我翻箱倒柜,把这份华为大牛总结的 Linux 归纳笔记找出来,免费共享给大家!
据说有小伙伴靠这份笔记顺利进入 BAT 哦,所以一定要好好学习这份资料!
资料介绍:
这份资料非常全面且详细,从 Linux 常用命令到 Linux 常用操作,再到网络管理、性能优化,几乎覆盖了 Linux 基础学习的方方面面,非常适合初学者入门!
资料也按目录进行编排,每一章下面都有更具体的内容:
而且,这份资料不是扫描版的,里面的文字都可以直接复制,非常便于我们学习:

Linux学习笔记(强悍总结值得一看).pdf(1.7 MB)

TabKey9 5楼回复 无名啊纯 SQL 还有啥策略,能更好地模糊识别 长地址 为 行政区划代码 呢?(有 5 级地区库) (2023-01-24//)
怕不是这个圈子里藏了你这么一位SQL大佬吧@无名啊
罐子 2楼回复 张小强有什么方式可以将web页面封装成apk (2023-01-24//)

@张小强,封装成小程序我试过,APP应该也是可以
一加8Pro

无名啊 1楼回复 张小强有什么方式可以将web页面封装成apk (2023-01-24//)

@张小强,一个木函、Fusion App 啥的可以么?(没咋用过,但记得有这个功能)

无名啊 4楼回复 无名啊纯 SQL 还有啥策略,能更好地模糊识别 长地址 为 行政区划代码 呢?(有 5 级地区库) (2023-01-24//)

@老虎会游泳,常规语言有啥算法吗?啥啥啥相似度?或者……?

人工智能大概怎么个过程呢?

无名啊 3楼回复 无名啊纯 SQL 还有啥策略,能更好地模糊识别 长地址 为 行政区划代码 呢?(有 5 级地区库) (2023-01-24//)

@卷心菜,不算啥大佬吧,只是 SQL 写起来繁杂,看起来复杂而已。实际思路很简单

老虎会游泳 2楼回复 无名啊纯 SQL 还有啥策略,能更好地模糊识别 长地址 为 行政区划代码 呢?(有 5 级地区库) (2023-01-24//)

能用纯SQL实现
要我的话肯定得用常规编程语言,甚至上人工智能

老虎会游泳 21楼回复 幕后导演求将这段js代码转成php (2023-01-24//)

@张小强,这里进行了i++

var ccc = '0c4a2013ebd12f0de2b54163fe318b1e'.charCodeAt(i++);
张小强 20楼回复 幕后导演求将这段js代码转成php (2023-01-24//)
@老虎会游泳,这段代码不是死循环吗?
虎老会泳游 2楼回复 tasy5kg[备忘]钛备份对 Android 13 存在兼容性问题 (2023-01-23//)
换了小高雄的脚本备份
胡椒舰长 9楼回复 上善若水给在用宝塔面板的人一点建议[减少面板被入侵风险] (2023-01-23//)

@上善若水,那为什么不用22的ssh正向代理呢?

下一页 上一页 (285 / 579页)

11月23日 05:48 星期天

本站由hu60wap6驱动

备案号: 京ICP备18041936号-1