我想写一个简单的加法器(giggles),它将每个参数相加并返回一个具有适当类型的和.目前,我有这个:
#include <iostream>
using namespace std;
template <class T>
T sum(const T& in)
{
return in;
}
template <class T, class... P>
auto sum(const T& t, const P&... p) -> decltype(t + sum(p...))
{
return t + sum(p...);
}
int main()
{
cout << sum(5, 10.0, 22.2) << endl;
}
Run Code Online (Sandbox Code Playgroud)
在GCC 4.5.1上,这似乎适用于2个参数,例如sum(2,5.5)返回7.5.但是,由于参数多于此,我得到的错误是sum()尚未定义.如果我这样声明sum():
template <class T, class P...>
T sum(const T& t, const P&... p);
Run Code Online (Sandbox Code Playgroud)
然后它适用于任意数量的参数,但sum(2,5.5)将返回整数7,这不是我所期望的.有两个以上的参数我假设decltype()必须进行某种递归才能推导出t + sum(p ...)的类型.这是合法的C++ 0x吗?或者decltype()仅适用于非可变参数声明吗?如果是这样的话,你会怎么写这样的功能?
在C++ 11中是否有可能重载const char*和字符串文字(const char[])?我们的想法是避免在strlen已知此长度时调用以查找字符串长度.
这个片段打破了G ++ 4.8和Clang ++ 3.2:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
template<typename T, int N>
void length(const T(&data)[N]) {
printf("%u[]\n", N - 1);
}
template<typename T>
void length(const T* data) {
printf("*%u\n", (unsigned)strlen(data));
}
int main() {
length("hello");
const char* p = "hello";
length(p);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
错误(Clang):
test2.cpp:16:3: error: call to 'length' is ambiguous
length("hello");
^~~~~~
test2.cpp:6:6: note: candidate function [with T = char, N = 6]
void length(const …Run Code Online (Sandbox Code Playgroud) 这个代码片段是否在ANSI C中定义良好?在我的系统(Linux x86_64)上,它似乎运行得很好并打印一个地址,但总是这样吗?例如,参数可能通过寄存器传递,并且获取该地址似乎不正确.
#include <stdio.h>
void foo(int a)
{
printf("%p\n", &a);
}
int main(void)
{
foo(42);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编辑:看起来GCC会在获取地址之前将寄存器传递的值放入堆栈.
<foo>:
55 push rbp
48 89 e5 mov rbp,rsp
48 83 ec 10 sub rsp,0x10
89 7d fc mov DWORD PTR [rbp-0x4],edi
b8 1c 06 40 00 mov eax,0x40061c
48 8d 55 fc lea rdx,[rbp-0x4]
48 89 d6 mov rsi,rdx
48 89 c7 mov rdi,rax
b8 00 00 00 00 mov eax,0x0
e8 d8 fe ff ff call 4003c0 <printf@plt> …Run Code Online (Sandbox Code Playgroud) 我对标准中的这一点不太确定.说我有三个这样的文件:
foo.h中
#include <iostream>
inline void foo();
void foo()
{
std::cout << "Foo" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
Foo.cpp中:
#include "foo.h"
void baz();
int main()
{
baz();
foo();
}
Run Code Online (Sandbox Code Playgroud)
bar.cpp
#include "foo.h"
void baz()
{
foo();
}
Run Code Online (Sandbox Code Playgroud)
现在,foo的定义将被编译为编译单元foo.o和bar.o. 如果我理解正确,内联函数将避免链接器冲突.G ++编译和链接这很好,但使用clang ++ 2.8我得到这个错误:
/tmp/cc-7RdmYP.o: In function `foo()':
bar.cpp:(.text+0x50): multiple definition of `foo()'
/tmp/cc-LW3id3.o:foo.cpp:(.text+0x50): first defined here
collect2: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)
看来clang ++并不是void foo()一个内联函数.但是,当我向定义添加内联时,它确实正常工作.
我是否必须在void foo()此处添加内联以将其视为内联函数,或者这是一个clang ++错误?
最近,我们在一些旧代码中发现了奇怪的行为.这段代码已经工作了很长时间,但在某些平台(XBox 360,PowerPC)上打破了编译器优化最大化.通常,我怀疑未定义的行为.
代码看起来大致如下:
#include <stdint.h>
uint32_t sign_extend16(uint32_t val)
{
return (int32_t)(int16_t)val;
}
Run Code Online (Sandbox Code Playgroud)
它是模拟器的一部分,所以有问题的操作不应该太奇怪.通常情况下,我希望这只考虑较低的16位并将其符号扩展为32位.显然,这是它多年来的行为.在x86_64上,GCC给出了这个结果:
0000000000000000 <sign_extend16>:
0: 0f bf c7 movswl %di,%eax
3: c3 retq
Run Code Online (Sandbox Code Playgroud)
但是,根据我对标准的理解,如果无法用signed类型表示unsigned的值,则无法定义将unsigned转换为signed.
那么编译器是否可以假设无符号值必须在范围内[0, 32767],因为任何其他值都是未定义的?在这种情况下,一个演员int16_t和另一个演员int32_t将无能为力.在这种情况下,编译器将代码转换为简单的移动是否合法?
因此,我们正在学校学习MIPS架构,我们正在实施MIPS32架构.我以为我会使用GNU cross-binutils作为汇编程序但是在处理jal,j和jr指令时我得到了奇怪的输出.汇编程序似乎将指令插入错误的位置.我不知道为什么会发生这种情况,我怀疑MIPS汇编程序会破坏,所以我认为这应该发生.
这是我的虚拟程序集文件:
.section .text
.globl __start
__start:
addi $a0, $0, 100
addi $a1, $0, 200
jal test
test:
add $v0, $a0, $a1
jr $ra
Run Code Online (Sandbox Code Playgroud)
但是,当我反汇编时,我得到这个输出:
Disassembly of section .text:
00000000 <__start>:
0: 20040064 addi a0,zero,100
4: 0c000003 jal c <test> <--- Why is jal coming before addi?
8: 200500c8 addi a1,zero,200
0000000c <test>:
c: 03e00008 jr ra <--- Why is jr coming before add?
10: 00851020 add v0,a0,a1
...
Run Code Online (Sandbox Code Playgroud)
这是一些建筑怪癖吗?如果是这样,这背后的理由是什么?
编辑:测试添加一些nop只是为了...
.section .text
.globl __start
__start:
addi $a0, $0, …Run Code Online (Sandbox Code Playgroud) 遵循这个问题:使用跳转(和链接)指令的奇怪的MIPS汇编程序行为我有一个工作的GNU程序集工具链用于我的单周期MIPS项目(没有分支延迟插槽!).我真的更喜欢用C语写.从编译器生成的代码本身确实运行,但我必须每次都手动编辑汇编源,因为GCC出于某种原因喜欢自动重新排序分支指令本身.我不想用脚本来破解这个,以确定何时重新排序分支.
有没有办法绕过这个?GCC出于某种原因生成这样的代码:
.set noreorder
...
jr $ra <-- GCC reordered for me!
addi $v0, $v0, 10 <--
...
.set reorder
Run Code Online (Sandbox Code Playgroud)
在哪里我真的想要为汇编程序提供这样的东西:
.set noreorder
addi $v0, $v0, 10
jr $ra
Run Code Online (Sandbox Code Playgroud) 我正在使用SDL 1.2.14,我发现了一个案例,我需要能够选择哪个监视器获取全屏窗口.使用Xorg,我发现Xinerama可以使用SDL_VIDEO_FULLSCREEN_HEAD环境变量完成这项工作,但是,我一直无法找到类似于Win32的东西.
全屏窗口始终在主监视器上创建,并且由于SDL 1.2不能(SDL 1.3可以,但它不稳定)提供API来选择在Win32上使用哪个监视器,我想知道是否可以以编程方式移动创建后使用Win32 API创建辅助监视器的全屏幕窗口.
我能够获得窗口/上下文的底层Win32句柄.
好吧,所以我对C++ iostream有一些问题感觉非常奇怪,但它可能是定义的行为,考虑到MSVC++和G ++都会发生这种情况.
说我有这个程序:
#include <iostream>
using namespace std;
int main()
{
int a;
cin >> a;
cout << a << endl;
cin >> a;
cout << a << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果我故意通过给第一个cin一个大于int的最大限制的值来溢出,所有进一步的调用cin.operator>>()将由于某种原因立即返回,并a设置为某个值.该值似乎未定义.
为什么以及这种行为记录在哪里?有没有办法弄清楚是否发生了这样的溢出?
此外,这个类似的程序似乎按照我的意图工作.如果我溢出该值,它将给出a一些值,并继续,就像溢出从未发生过一样.
#include <cstdio>
using namespace std;
int main()
{
int a;
scanf("%d", &a);
printf("%d\n", a);
scanf("%d", &a);
printf("%d\n", a);
scanf("%d", &a);
printf("%d\n", a);
return 0;
}
Run Code Online (Sandbox Code Playgroud)