小编Wil*_*ill的帖子

严格的混叠似乎不一致

有一些来自严格别名的错误,所以我想我会尝试修复所有错误.在详细了解它的情况后,有时GCC似乎没有发出警告,而且有些事情也无法实施.至少根据我的理解,下面的每一个都被打破了 那么我的理解是错误的,是否有正确的方法来完成所有这些事情,或者某些代码是否必须在技术上打破规则并被系统测试很好地覆盖?

这些错误来自一些代码,其中char和unsigned char缓冲区混合在一起,例如如下所示:

size_t Process(char *buf, char *end)
{
    char *p = buf;
    ProcessSome((unsigned char**)&p, (unsigned char*)end);
    //GCC decided p could not be changed by ProcessSome and so always returned 0
    return (size_t)(p - buf);
}
Run Code Online (Sandbox Code Playgroud)

将此更改为下面似乎可以解决问题,虽然它仍然涉及演员阵容所以我不确定为什么现在这样做并且没有警告:

size_t Process(char *buf, char *end)
{
    unsigned char *buf2 = (unsigned char *)buf;
    unsigned char *p = buf2;
    unsigned char *end2 = (unsigned char*)end;
    ProcessSome(&p, end2);
    return (size_t)(p - buf2);
}
Run Code Online (Sandbox Code Playgroud)

此外还有许多其他地方似乎没有任何警告

//contains a unsigned char* of data. Possibly from the network, …
Run Code Online (Sandbox Code Playgroud)

c++ gcc strict-aliasing

5
推荐指数
1
解决办法
429
查看次数

覆盖文件而不会有文件损坏的风险

我的应用程序经常想要保存文件以便稍后再次加载。最近不幸发生了崩溃,我想以这样的方式编写操作,以保证我要么拥有新数据,要么拥有原始数据,但没有损坏的混乱。

我的第一个想法是按照以下方式做一些事情(保存一个名为 example.dat 的文件):

  1. 为目标目录指定一个唯一的文件名,例如 example.dat.tmp
  2. 创建该文件并将我的数据写入其中。
  3. 删除原始文件(example.dat)
  4. 将临时文件重命名(“移动”)到原始文件所在的位置(example.dat.tmp -> example.dat)。

然后在加载时应用程序可以遵循以下规则:

  • 如果没有“example.dat”并且没有“example.dat.tmp”,则首先运行/新项目,因此加载默认值/创建新文件。
  • 如果“example.dat”且没有“example.dat.tmp”,则加载 example.dat(正常负载情况)
  • 如果“example.dat.tmp”存在,则为用户提供潜在恢复数据的机会。如果“example.dat”也存在,则在没有显式用户常量的情况下不要覆盖它。

然而,经过一些研究,我发现除了我可以使用文件刷新方法覆盖的操作系统缓存之外,一些磁盘驱动器仍然在内部进行缓存,甚至可能对操作系统撒谎说它们已经完成,所以 4 .可以完成,但写入实际上并未写入,如果系统出现故障,我就会丢失数据......

我不确定磁盘问题实际上可以通过应用程序解决,但是上面的一般规则是否正确?我是否应该保留文件的旧恢复副本更长时间才能确定,有关此类事情的准则是什么(例如可接受的磁盘使用情况,用户是否应该选择,将此类文件放在何处等)。

另外,我应该如何避免用户和“example.dat.tmp”的其他程序之间的潜在冲突。我记得有时会从其他软件中看到“~example.dat”,这是一个更好的约定吗?

c++ linux windows file-io

5
推荐指数
1
解决办法
2577
查看次数

标签 统计

c++ ×2

file-io ×1

gcc ×1

linux ×1

strict-aliasing ×1

windows ×1