小编Nor*_*ame的帖子

什么属于教育工具,以展示人们在C/C++中做出的无根据的假设?

我想为SO准备一些教育工具,这应该有助于初学者(和中级)程序员识别和挑战他们在C,C++及其平台中的无根据的假设.

例子:

  • "整数环绕"
  • "每个人都有ASCII"
  • "我可以将函数指针存储在void*中"

我认为可以在各种平台上运行一个小型测试程序,它运行"合理的"假设,根据我们在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)

c c++ portability cross-platform

120
推荐指数
8
解决办法
8933
查看次数

如何修复这个已有 8 年历史的 VBA 64 位编译器错误?

所以这是错误:在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 …

excel 64-bit ms-access vba class-terminate

58
推荐指数
1
解决办法
1万
查看次数

如果我们在C/C++中添加安全签名/无符号比较,它会破坏语言或现有代码吗?

在阅读了有关签名/未签名比较的问题之后(我每隔几天就会说出来):

我想知道为什么我们没有正确的签名无符号比较,而是这个可怕的混乱?从这个小程序中获取输出:

#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)

c c++ comparison unsigned signed

20
推荐指数
3
解决办法
1038
查看次数

c ++:用随机字节填充缓冲区的最快方法

我有这个大字符数组需要填充高频率的随机字节.我想知道除了天真的方式(使用for循环 - 用随机字节填充每个单元格)之外是否有更快的方法来执行此操作.对值的随机质量没有要求.任何"随机"垃圾都可以.平台是窗户

c++ windows winapi

18
推荐指数
2
解决办法
2万
查看次数

如何将true/false/unknown映射到-1/0/null而不重复?

我目前正在开发一个工具来帮助我的用户将他们的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中是不可能的,因为:

  1. 列不能具有布尔类型(列值不能和')
  2. 在期望表达式的地方不能使用逻辑谓词.

因此,我的转换例程将上述语句转换为:

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)

sql t-sql sql-server sql-server-2005

8
推荐指数
1
解决办法
3094
查看次数

clang vs gcc:不同的易失性访问代码

考虑这个例子:

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)在易失性访问时拒绝?谁错了?

c++ assembly gcc volatile clang

7
推荐指数
1
解决办法
226
查看次数

你如何打开一个已经cd到特定路径的终端?

如何使用终端打开另一个终端窗口但是使用我指定的路径?

当我上班的时候,我正在使用automator加载我的工作,但我需要知道如何做到这一点:

打开终端并输入:
•cd工作/公司/项目/
•脚本/服务器

然后在该终端窗口中的新选项卡和CD到同一文件夹.

macos terminal applescript

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

如何避免编写同一循环的多个版本

在一个大循环中,我目前有一个类似的声明

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 c++

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

头文件中的类

我正在使用的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头类中.任何想法为什么这不起作用?

c++ virtual header function

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