我想为SO准备一些教育工具,这应该有助于初学者(和中级)程序员识别和挑战他们在C,C++及其平台中的无根据的假设.
例子:
我认为可以在各种平台上运行一个小型测试程序,它运行"合理的"假设,根据我们在SO中的经验,通常是由许多缺乏经验/半经验的主流开发人员制作的,并记录他们在各种机器上打破的方式.
这样做的目的不是要证明做某事是"安全的"(这是不可能做到的,测试只有在他们破坏的情况下证明了什么),而是向最难以理解的个体展示最不起眼的表达方式如果它具有未定义或实现定义的行为,则在另一台机器上中断..
为此,我想问你:
这是测试玩具的当前版本:
#include <stdio.h>
#include <limits.h>
#include <stdlib.h>
#include <stddef.h>
int count=0;
int total=0;
void expect(const char *info, const char *expr)
{
printf("..%s\n but '%s' is false.\n",info,expr);
fflush(stdout);
count++;
}
#define EXPECT(INFO,EXPR) if (total++,!(EXPR)) expect(INFO,#EXPR)
/* stack check..How can I do this better? */
ptrdiff_t check_grow(int k, int *p)
{
if (p==0) p=&k;
if (k==0) return &k-p;
else return check_grow(k-1,p);
}
#define BITS_PER_INT (sizeof(int)*CHAR_BIT)
int bits_per_int=BITS_PER_INT;
int int_max=INT_MAX; …Run Code Online (Sandbox Code Playgroud) 所以这是错误:在64 位VBA 主机(例如 Access 365 64 位或 Excel 2016 64 位)中创建一个类模块SomeClass:
' this needs to be here to trigger the bug:
Private Sub Class_Terminate()
End Sub
Run Code Online (Sandbox Code Playgroud)
然后是一些模块Test:
Function ReturnFalse(o As Object) As Boolean
ReturnFalse = False
End Function
Sub Test()
Debug.Print ReturnFalse(New SomeClass)
If ReturnFalse(New SomeClass) Then
Debug.Print True
Else
Debug.Print False
End If
End Sub
Run Code Online (Sandbox Code Playgroud)
现在,如果您使用的是32 位VBA 主机并在即时窗口中运行“测试” ,则会显示预期结果:
False
False
Run Code Online (Sandbox Code Playgroud)
但是,如果您使用的是64 位VBA 主机,则会出现:
False
True
Run Code Online (Sandbox Code Playgroud)
除了,当您删除或重命名Class_Terminate()sub …
在阅读了有关签名/未签名比较的问题之后(我每隔几天就会说出来):
我想知道为什么我们没有正确的签名无符号比较,而是这个可怕的混乱?从这个小程序中获取输出:
#include <stdio.h>
#define C(T1,T2)\
{signed T1 a=-1;\
unsigned T2 b=1;\
printf("(signed %5s)%d < (unsigned %5s)%d = %d\n",#T1,(int)a,#T2,(int)b,(a<b));}\
#define C1(T) printf("%s:%d\n",#T,(int)sizeof(T)); C(T,char);C(T,short);C(T,int);C(T,long);
int main()
{
C1(char); C1(short); C1(int); C1(long);
}
Run Code Online (Sandbox Code Playgroud)
用我的标准编译器(gcc,64bit)编译,我得到这个:
char:1
(signed char)-1 < (unsigned char)1 = 1
(signed char)-1 < (unsigned short)1 = 1
(signed char)-1 < (unsigned int)1 = 0
(signed char)-1 < (unsigned long)1 = 0
short:2
(signed short)-1 < (unsigned char)1 = 1
(signed short)-1 < (unsigned short)1 = 1
(signed short)-1 < …Run Code Online (Sandbox Code Playgroud) 我有这个大字符数组需要填充高频率的随机字节.我想知道除了天真的方式(使用for循环 - 用随机字节填充每个单元格)之外是否有更快的方法来执行此操作.对值的随机质量没有要求.任何"随机"垃圾都可以.平台是窗户
我目前正在开发一个工具来帮助我的用户将他们的SQL代码移植到SQL-Server 2005.为此,我将SQL解析为语法树,分析它需要注意的构造,修改它并将其转换回T - SQL.
在我想支持的事情上,其他RDBMS的"bools is values too"语义.例如,MS-Access允许我编写select A.x and A.y as r from A,这在T-SQL中是不可能的,因为:
因此,我的转换例程将上述语句转换为:
select case
when (A.x<>0) and (A.y<>0)
then -1
when not((A.x<>0) and (A.y<>0))
then 0
else
null
end as r
from A;
Run Code Online (Sandbox Code Playgroud)
哪个有效,但很烦人,因为我必须复制逻辑表达式(可能非常复杂或包含子查询等)以区分true,false并且unknown- 后者应映射为null.所以我想知道T-SQL专业人员是否知道更好的方法来实现这一目标?
更新: 我想指出的是,该解决方案,尽量保持操作数的整数域必须考虑到,即一些操作数可以是逻辑表达式首位.这意味着需要一种将bool转换为值的有效解决方案.例如:
select A.x and exists (select * from B where B.y=A.y) from A;
Run Code Online (Sandbox Code Playgroud) 考虑这个例子:
volatile unsigned int x;
unsigned int y;
void f() {
x /= 2;
}
void g() {
y /= 2;
}
Run Code Online (Sandbox Code Playgroud)
当使用-Os编译时,clang-6.0在x64上为f和g生成相同的shrl <offset>(%rip)指令模式(参见https://godbolt.org/g/hUPprL),而gcc-7.3生成此参数(请参阅https:// godbolt. org/g/vMcKVV)对于f():
mov 0x200b67(%rip),%eax # 601034 <x>
shr %eax
mov %eax,0x200b5f(%rip) # 601034 <x>
Run Code Online (Sandbox Code Playgroud)
这只是一个错过的优化,还是有理由让gcc shrl <offset>(%rip)在易失性访问时拒绝?谁错了?
如何使用终端打开另一个终端窗口但是使用我指定的路径?
当我上班的时候,我正在使用automator加载我的工作,但我需要知道如何做到这一点:
打开终端并输入:
•cd工作/公司/项目/
•脚本/服务器
然后在该终端窗口中的新选项卡和CD到同一文件夹.
在一个大循环中,我目前有一个类似的声明
if (ptr == NULL || ptr->calculate() > 5)
{do something}
Run Code Online (Sandbox Code Playgroud)
其中ptr是在循环之前设置的对象指针,从不更改.
我想避免在循环的每次迭代中将ptr与NULL进行比较.(当前的最终程序就是这样做的,对吗?)一个简单的解决方案是为(ptr == NULL)编写一次循环代码,为(ptr!= NULL)编写一次.但这会增加代码量,使维护更加困难,而且如果相同的大循环出现两次只有一行或两行更改,则看起来很傻.
我能做什么?使用动态值常量可能并希望编译器是智能的?怎么样?
非常感谢!
由Luther Blissett 编辑.OP想要知道是否有更好的方法来删除指针检查:
loop {
A;
if (ptr==0 || ptr->calculate()>5) B;
C;
}
Run Code Online (Sandbox Code Playgroud)
比复制循环,如下所示:
if (ptr==0)
loop {
A;
B;
C;
}
else loop {
A;
if (ptr->calculate()>5) B;
C;
}
Run Code Online (Sandbox Code Playgroud) 我正在使用的C++程序遇到一些麻烦.我用一个纯虚方法创建了一个抽象类.由于该类没有变量或实现的方法,我将该类存储在没有.cpp实现文件的头文件中(没有任何需要).
方法是:
virtual void handleEvent() = 0;
Run Code Online (Sandbox Code Playgroud)
问题是当我从该类继承并实现该方法时:
virtual void handleEvent(); (.h file)
void handleEvent(){.....} (.cpp file)
Run Code Online (Sandbox Code Playgroud)
我收到编译器错误(使用g ++):
(.rodata._ZtV10Engine[vtable for Engine]+0x8): undefined reference to Engine::handleEvent()
Run Code Online (Sandbox Code Playgroud)
该文件包含在Engine头类中.任何想法为什么这不起作用?