上下文:
受保护和公共类成员的继承是面向对象编程的基本概念.下面的简单示例说明了一个经常遇到的情况,其中类CDerived继承了类的所有公共成员,CBase并添加了自己的1个附加函数,而不更改或显式重新定义或重新定义类的任何公共成员CBase.
#include <stdio.h>
class CBase
{
public:
char Arr[32];
int Fn1(void) {
return Arr[1] ^ Arr[sizeof(Arr)-1];
}
int Fn2(void) {
return Arr[2] ^ Arr[sizeof(Arr)-2];
}
};
class CDerived : public CBase
{
public:
int FnSum(void) {
return Fn1() + Fn2();
}
};
int main(void)
{
CDerived ddd;
printf("%d\n", ddd.Fn1());
printf("%d\n", ddd.Fn2());
printf("%d\n", ddd.FnSum());
return (int)ddd.Arr[0];
};
Run Code Online (Sandbox Code Playgroud)
上面的代码在所有主要编译器上编译都没有问题.
但是,如果希望" 模板化 "此代码,例如:通过参数化Arr数组的大小,那么CBase类模板的所有公共成员对CDerived符合最新C++标准的编译器上的类模板都是不可见的.
以下是问题代码:
#include <stdio.h>
template …Run Code Online (Sandbox Code Playgroud) 该声明:
volatile unsigned char * volatile p = (volatile unsigned char * volatile)v;
Run Code Online (Sandbox Code Playgroud)
在MSVC v14.1中生成警告C4197:
警告C4197:'volatile unsigned char*volatile':忽略强制转换中的顶级volatile
2011 C标准([N1570] 6.7.3 4.)规定:"与限定类型相关联的属性仅对表达式有意义,即l值",因此此投射中的顶级volatile将被忽略并生成这个警告.
该代码的作者指出,它不违反C标准,并且需要阻止一些GCC优化.他通过以下代码说明了代码的问题:https://godbolt.org/g/xP4eGz
#include <stddef.h>
static void memset_s(void * v, size_t n) {
volatile unsigned char * p = (volatile unsigned char *)v;
for(size_t i = 0; i < n; ++i) {
p[i] = 0;
}
}
void f1() {
unsigned char x[4];
memset_s(x, sizeof x);
}
static void memset_s_volatile_pnt(void * v, size_t n) {
volatile unsigned …Run Code Online (Sandbox Code Playgroud) After creating an iterative (non-recursive) function, that enumerates doubly restricted compositions of positive integers in a lexicographic order, for a microcontroller with a very small amount of RAM (but large EPROM), I had to expand the number of restrictions to 3, namely to:
The original function, that generates the doubly restricted compositions is listed …
这个问题与Convert Cygwin path to Windows path in a makefile有关,但并不相同。
我需要转换 Windows 路径,例如:
C:\src\bin
Run Code Online (Sandbox Code Playgroud)
进入 Unix 路径,例如:
/c/src/bin
Run Code Online (Sandbox Code Playgroud)
在 makefile 中,我可以使用以下代码来转换此类路径:
slashedpath = $(subst \\,\/,$(windowspath))
unixpath = $(shell cygpath -u $(slashedpath))
Run Code Online (Sandbox Code Playgroud)
当cygpath函数不可用时,如何在 GNU Make 正在处理的 makefile 中执行相同的转换?
ps 如果$(windowspath)包含多个路径怎么办?如何将它们全部转换?
我如何告诉MSVC编译器使用64位/ 32位除法运算来为x86-64目标计算以下函数的结果:
#include <stdint.h>
uint32_t ScaledDiv(uint32_t a, uint32_t b)
{
if (a > b)
return ((uint64_t)b<<32) / a; //Yes, this must be casted because the result of b<<32 is undefined
else
return uint32_t(-1);
}
Run Code Online (Sandbox Code Playgroud)
我希望代码在if语句为true时编译为使用64位/ 32位除法运算,例如:
; Assume arguments on entry are: Dividend in EDX, Divisor in ECX
mov edx, edx ;A dummy instruction to indicate that the dividend is already where it is supposed to be
xor eax,eax
div ecx ; EAX = EDX:EAX / ECX
Run Code Online (Sandbox Code Playgroud)
...但是x64 …
如何哄骗GCC编译器在普通C中发出REPE CMPSB指令,而没有"asm"和"_emit"关键字,调用包含的库和编译器内在函数?
我尝试了一些像下面列出的C代码,但没有成功:
unsigned int repe_cmpsb(unsigned char *esi, unsigned char *edi, unsigned int ecx) {
for (; ((*esi == *edi) && (ecx != 0)); esi++, edi++, ecx--);
return ecx;
}
Run Code Online (Sandbox Code Playgroud)
请参阅GCC如何在此链接上编译它:https:
//godbolt.org/g/obJbpq
PS
我意识到无法保证编译器以某种方式编译C代码,但我还是想哄它以获得乐趣,只是为了看它有多聪明.
可以通过硬件128bit / 64bit除法指令执行缩放的64bit / 32bit除法,例如:
; Entry arguments: Dividend in EAX, Divisor in EBX
shl rax, 32 ;Scale up the Dividend by 2^32
xor rdx,rdx
and rbx, 0xFFFFFFFF ;Clear any garbage that might have been in the upper half of RBX
div rbx ; RAX = RDX:RAX / RBX
Run Code Online (Sandbox Code Playgroud)
...在某些特殊情况下,比硬件64位/ 32位除法指令执行的缩放64位/ 32位除法更快,例如:
; Entry arguments: Dividend in EAX, Divisor in EBX
mov edx,eax ;Scale up the Dividend by 2^32
xor eax,eax
div ebx ; EAX = EDX:EAX / EBX
Run Code Online (Sandbox Code Playgroud)
“某些特殊情况”是指异常的红利和除数。我只想比较 …
如何更紧凑地初始化和返回向量的向量?下面的代码看起来臃肿,重复的两种情况时,K==1和K==N。
std::vector< std::vector<unsigned int> > Foobar(const unsigned int K, const unsigned int N)
{
std::vector< std::vector<unsigned int> > res;
if (K == 1)
{
std::vector<unsigned int> r(1,N); //One N.
res.emplace_back(r);
return res;
}
if (K == N)
{
std::vector<unsigned int> r(N,1); //N ones.
res.emplace_back(r);
return res;
}
PopulateVectors(res, K+1, N+1);
PopulateVectors(res, K, N);
return res;
}
Run Code Online (Sandbox Code Playgroud)
该函数PopulateVectors()接受res作为引用并将多个向量插入其中。它内部的工作方式对这个问题无关紧要。