小编Mai*_*ter的帖子

使用具有可变参数模板函数的decltype的尾随返回类型

我想写一个简单的加法器(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++ templates variadic-functions decltype c++11

38
推荐指数
3
解决办法
5626
查看次数

是否有可能合法地重载字符串文字和const char*?

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

c++ templates overloading c++11

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

获取函数参数的地址是否合法?

这个代码片段是否在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)

c function

11
推荐指数
2
解决办法
2922
查看次数

内联限定符源于原型或定义?

我对标准中的这一点不太确定.说我有三个这样的文件:

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 ++错误?

c++ gcc clang

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

符合标准的编译器是否可以破坏uint32_t - > int16_t - > int32_t转换?

最近,我们在一些旧代码中发现了奇怪的行为.这段代码已经工作了很长时间,但在某些平台(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将无能为力.在这种情况下,编译器将代码转换为简单的移动是否合法?

c integer-overflow

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

使用跳转(和链接)指令的奇怪的MIPS汇编程序行为

因此,我们正在学校学习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)

assembly mips disassembly binutils

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

如何关闭MIPS-GCC自动指令重新排序?

遵循这个问题:使用跳转(和链接)指令的奇怪的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)

assembly gcc mips

6
推荐指数
2
解决办法
3772
查看次数

使用Win32/SDL将全屏窗口移动到辅助监视器

我正在使用SDL 1.2.14,我发现了一个案例,我需要能够选择哪个监视器获取全屏窗口.使用Xorg,我发现Xinerama可以使用SDL_VIDEO_FULLSCREEN_HEAD环境变量完成这项工作,但是,我一直无法找到类似于Win32的东西.

全屏窗口始终在主监视器上创建,并且由于SDL 1.2不能(SDL 1.3可以,但它不稳定)提供API来选择在Win32上使用哪个监视器,我想知道是否可以以编程方式移动创建后使用Win32 API创建辅助监视器的全屏幕窗口.

我能够获得窗口/上下文的底层Win32句柄.

winapi sdl multiple-monitors

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

为什么整数溢出会导致C++ iostream出错?

好吧,所以我对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)

c++ integer-overflow

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