Tag: standard library

memchr()如何在引擎盖下工作?

背景:我正在尝试创建一个纯D语言实现的function,大致相当于C的memchr,但使用数组和索引而不是指针。 原因是std.string将用于编译时function评估。 对于那些不熟悉的w / D,如果满足某些限制,可以在编译时评估函数。 一个限制是它们不能使用指针。 另一个是他们无法调用C函数或使用内联汇编语言。 使字符串库在编译时工作对于某些编译时代码生成很有用。 问题: memchr如何在引擎盖下工作以尽可能快地执行? 在Win32上,我使用简单循环在纯D中创建的任何东西,即使有明显的优化技术,例如禁用边界检查,循环展开等,也至少要慢2倍。有哪些非显而易见的技巧可用于像在字符串中查找字符一样简单?

`strtod(“3ex”,&end)应该是什么结果? 怎么样`sscanf`?

在我的实验中这个表达 double d = strtod(“3ex”, &end); 用3.0初始化d并将end指针放在输入字符串中的’e’字符处。 这正如我所期望的那样。 ‘e’字符可能看起来是指数部分的开头,但由于缺少实际指数值(6.4.4.2要求),因此’e’应被视为完全独立的字符。 但是,当我这样做的时候 double d; char c; sscanf(“3ex”, “%lf%c”, &d, &c); 我注意到sscanf消耗%lf格式说明符的’3’和’e’ 。 变量d接收3.0值。 变量c以’x’结尾。 这看起来很奇怪有两个原因。 首先,由于语言规范在描述%f格式说明符的行为时引用了strtod ,我直观地期望%lf以与strtod相同的方式处理输入(即选择与终止点相同的位置)。 但是,我知道历史上scanf应该返回不超过一个字符回输入流。 这限制了任何超前scanf的距离可以由一个字符执行。 上面的例子需要至少两个字符前瞻。 所以,假设我接受%lf从输入流中消耗’3’和’e’的事实。 但后来我们遇到了第二个问题。 现在sscanf必须将”3e”转换为double类型。 “3e”不是浮点常数的有效表示(同样,根据6.4.4.2,指数值不是可选的)。 我希望sscanf将此输入视为错误:在%lf转换期间终止,返回0并保持d和c不变。 但是,上面的sscanf成功完成(返回2 )。 这种行为在标准库的GCC和MSVC实现之间是一致的。 所以,我的问题是,在C语言标准文档中它确实允许sscanf如上所述行为,参考上述两点:消耗比strtod更多的function并成功地将这样的序列转换为”3e” ? 通过查看我的实验结果,我可以“反向工程” sscanf的行为:消耗尽可能多的“看起来正确”从不退后,然后将消耗的序列传递给strtod 。 那种’e’被%lf消耗然后被strtod忽略的方式。 但究竟是语言规范中的所有内容吗?