- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
有时在C语言中,有必要从部分写入的数组中读取可能写入的项目,例如:
如果已写入该项目,则读取将产生实际上已写入的值,并且
如果尚未写入该项目,则读取会将未指定的位模式转换为适当类型的值,而不会产生副作用。
从头开始找到解决方案的成本很高,但是验证所提出的解决方案的成本却很低。如果一个数组在所有情况下都具有解决方案,而在其他情况下则具有任意位模式,则读取该数组,测试其是否持有有效的解决方案,并仅在数组中的解决方案无效时才慢慢计算该解决方案,可能是有用的优化。
如果可以保证尝试读取类型如uint32_t
的未写数组元素总是产生适当类型的值,那么有效地,这种方法将是简单而直接的。即使该要求仅适用于unsigned char
,它仍然可能可行。不幸的是,编译器有时的行为似乎是读取不确定的值,即使类型为unsigned char
,也可能会产生与该类型的值不一致的行为。此外,“缺陷报告”中的讨论表明,涉及不确定值的运算会产生不确定结果,因此,即使给出unsigned char x, *p=&x; unsigned y=*p & 255; unsigned z=(y < 256);
之类的内容,z
也有可能接收值0
。
据我所知,该函数:
unsigned char solidify(unsigned char *p)
{
unsigned char result = 0;
unsigned char mask = 1;
do
{
if (*p & mask) result |= mask;
mask += (unsigned)mask; // Cast only needed for capricious type ranges
} while(mask);
return result;
}
unsigned char
的值,即使该存储恰好持有不确定值也是如此。但是,鉴于获得所需效果所需的机器代码通常应等效于返回
x
,因此这种方法似乎很慢且笨拙。
unsigned char
范围内的值?
fwrite
可以用于部分扭曲的结构或数组,我都认为可以以这种方式使用的I / O例程(为未设置的部分写入任意值)应为比在这种情况下可能会跳脱的质量更高。
unsigned char solidify_alt(unsigned char *p)
{ return *p; }
unsigned char
的地址优化为例如。一个32位寄存器,上面的函数可能会盲目地返回该寄存器的内容,而不会将其裁剪到0-255的范围内。如果这是唯一的问题,则要求调用者手动裁剪此类函数的结果将很烦人,但可以生存。不幸...
void send_byte(unsigned char *p, unsigned int n)
{
while(n--)
OUTPUT_REG = solidify_alt(*p++) | 0x0200;
}
void send_string4(char *st)
{
unsigned char buff[5]; // Leave space for zero after 4-byte string
strcpy((char*)buff, st);
send_bytes(buff, 4);
}
solidify_alt
而不是
solidify
,因此编译器可以合法地将其转换为:
void send_string4(char *st)
{
unsigned buff0, buff1, buff2, buff3;
buff0 = st[0]; if (!buff0) goto STRING_DONE;
buff1 = st[1]; if (!buff1) goto STRING_DONE;
buff2 = st[2]; if (!buff2) goto STRING_DONE;
buff3 = st[3];
STRING_DONE:
OUTPUT_REG = buff0 | 0x0200;
OUTPUT_REG = buff1 | 0x0200;
OUTPUT_REG = buff2 | 0x0200;
OUTPUT_REG = buff3 | 0x0200;
}
((unsigned char)solidify_alt(*p++) | 0x0200) & 0x02FF)
,编译器仍可以简化该表达式以产生上面给出的代码。
最佳答案
这不是答案,而是扩展的评论。
立即的解决方案是让编译器提供一个内置的(例如assume_initialized(variable [, variable ... ]*)
),该生成器不生成任何机器代码,而只是使编译器将要定义但未知的指定变量(标量或数组)的内容。
例如,使用另一个编译单元中定义的伪函数可以达到类似的效果
void define_memory(void *ptr, size_t bytes)
{
/* Nothing! */
}
define_memory(some_array, sizeof some_array)
),以阻止编译器将数组中的值视为不确定的;之所以可行,是因为在编译时,编译器无法确定是否未指定值,因此必须考虑将其指定为已定义(已定义但未知)。
memrepeat(ptr, first, bytes)
函数:对于
memmove()
,与
memcpy()
相对应的函数将重复
first
到
ptr
到
ptr+first
的字节。像
ptr+bytes-1
一样,它将对数据的存储表示形式起作用,因此,即使
memmove()
到
ptr
包含陷阱表示形式,也不会实际触发陷阱。
double nums[7] = { 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 };
memrepeat(nums, 2 * sizeof nums[0], sizeof nums);
double nums[7] = { 7.0, 6.0, 7.0, 6.0, 7.0, 6.0, 7.0 };
ptr+first
,其中
memsetall(data, size, count)
是重复存储单元的大小,而
size
存储单元总数(因此< cc>单元实际上是被复制的。)特别是,这使得使用非临时性存储来进行复制的简单实现(从初始存储单元读取);另一方面,
count
只能复制完整存储单元,与
count-1
不同,
memsetall()
将使
memrepeat()
中的第7个元素保持不变-即,在上面的示例中,它的产量为
memsetall(nums, 2 * sizeof nums[0], 3);
。)
nums[]
或
{ 7.0, 6.0, 7.0, 6.0, 7.0, 6.0, 1.0 }
,甚至可以针对特定的体系结构和编译器对其进行优化,但是编写可移植的优化版本却很困难。
memrepeat()
(或
memsetall()
)的基于循环的实现在通过例如GCC,因为编译器无法将函数调用模式合并到单个操作中。
memcpy()
和
memmove()
内联到目标和用例优化的内部版本中,并且对于这样的
memcpy()
和/或
memmove()
函数执行此操作将使其可移植。在x86-64上的Linux中,GCC内联已知大小的调用,但是将函数调用保留在仅在运行时知道大小的地方。
memrepeat()
,
memsetall()
和
getline()
首先加入;它们对我们可以教新的C程序员的代码产生更大的积极影响。)
关于c - 从不确定值到未指定值的有效转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47611338/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!