홈>
나는 다음 코드로 장난을 쳤으며 Visual Studio 2017 응용 프로그램과 두 개의 다른 온라인 컴파일러를 사용하여 다른 결과를 얻었습니다. 릴리스 모드에서 Visual Studio는 두 경우 모두 복사/이동을 제거하지만 두 온라인 컴파일러는 괄호로 묶지 않은 return 문의 경우에만 수행합니다. 내 질문은 : 누가 옳고 더 중요한 것은 기본 규칙이 무엇인가입니다. (
decltype(auto)
와 함께 괄호를 사용할 수 있다는 것을 알고 있습니다.
통사론. 그러나 이것은 현재 사용 사례가 아닙니다.)
예제 코드 :
#include <iostream>
#include <cstdio>
struct Foo
{
Foo() { std::cout << "default constructor" << std::endl; }
Foo(const Foo& rhs) { std::cout << "copy constructor" << std::endl; }
Foo(Foo&& rhs) { std::cout << "move constructor" << std::endl; }
Foo& operator=(const Foo& rhs) { std::cout << "copy assignment" << std::endl; return *this; }
Foo& operator=(Foo&& rhs) { std::cout << "move assignment" << std::endl; return *this; }
};
Foo foo_normal()
{
Foo a{};
return a;
}
Foo foo_parentheses()
{
Foo a{};
return (a);
}
int main()
{
auto a = foo_normal();
auto b = foo_parentheses();
std::getchar();
}
온라인 컴파일러 1 : http://cpp.sh/75bux
온라인 컴파일러 2 : http://coliru.stacked-crooked.com/a/c266852b9e1712f3>릴리스 모드에서 Visual Studio의 출력은 다음과 같습니다.
default constructor
default constructor
다른 두 컴파일러에서 결과는 다음과 같습니다 :
default constructor
default constructor
move constructor
- 답변 # 1
- 답변 # 2
이 표준의 관련 인용문입니다 :
와이즈 비즈따라서 요구 사항은
<올>반환 진술서
함수에서
클래스 리턴 유형 사용
표현식이 비 휘발성 자동 객체의 이름 인 경우 (함수 매개 변수 또는 핸들러의 예외 선언 ([except.handle])에 의해 도입 된 변수 제외)
함수 반환 타입과 같은 타입 (cv-qualification 무시)
요구 사항 1, 2, 3 및 5는 충족되었지만 주장 4는 그렇지 않다고 주장한다. 와이즈 비즈 객체의 이름이 아닙니다. 따라서 주어진 코드에 대해서는 복사 제거가 적용되지 않습니다. 이동 생성자는 부작용이 있으므로 as-if 규칙에 따라 제거 할 수 없습니다.
그러므로 gcc가 옳고 여기에 비주얼 스튜디오 (및 클랜)가 잘못되었습니다.
return
관련 자료
- scala - my_udf 메소드에는 return 문이 있습니다 결과 유형이 필요합니다
- function - JavaScript 삼항 연산자 표현식 내의 return 문
- php - 준비된 명령문 리턴 오류 번호 0
- javascript - return 문은 분명히 아무것도 반환하지 않습니다
- c - 재귀 요인 반환 진술
- python - return 문 후 루프 계속, 중지 방법
- 파이썬 함수의 return 문은 문자열을 print (argument, end = '')와 같은 줄에 어떻게 유지할 수 있습니까?
- c# - 이 '반환'진술을 제거하거나 조건부로 작성하십시오
- javascript - return 문이 있고 변수에 NodeJS 값이 있어도 undefined를 반환합니다
- 파이썬의 함수 내에서 for 루프의 return 문
- 자바 스크립트 - return 문이 여러 줄에 걸쳐있는 깔끔한 방법
- c# - 스위치 케이스 문의 반환 값
- python - 인쇄하는 동안 return 문이 텍스트를 반환하지 않는 이유는 무엇입니까?
- php - 준비된 명령문은 항상 false를 리턴합니다
- python - 모든 행을 반환하지 않는 return 문으로 함수를 수정하는 방법
- android - Kotlin은 함수 서명에 일부 리턴 유형이있는 함수에서 return 문을 확인하지 않습니다
- d - 함수의 return 문이 평범하지 않은 이유 int []
- c++ - cuda - constexpr if function에서 "void가 아닌 함수 끝에 반환 문이 없습니다"
- mysql - 또는 명령문 결과가 SQL에서 온 반환
- android - Int를 반환하는 함수가 if 문의 일부가 될 수있는 방법은 무엇입니까?
관련 질문
- c++ : 현재 표준에서 템플릿 인스턴스화의 2 단계 이름 조회 관련 규칙은 어디에 있습니까?
- c++ : Clang이 참조 및 Null이 아닌 포인터 인수에 대해 다른 code를 생성하는 이유는 무엇입니까?
- 임시 객체의 주소가 c++에서 임시 객체가있는 객체의 주소와 동일한 이유
- c++ : [temp.spec] /5과 [basic.odr] w.r.t간에 충돌이 있습니까? 명시 적 전문화에 대한 odr 규칙?
- c++ : strtoull은 항상 유효한 숫자를 반환하거나 errno를 설정합니까?
- c++ - 이것은 C ++의 멤버 액세스 규칙에 대한 올바른 요약입니까?
GCC가 옳다.
[class.copy.elision] 단락 1에 따르면 :
와이즈 비즈 와이즈 비즈 표현식이비 휘발성 자동 객체의 이름인 경우 (<매개 변수 또는<함수 반환 유형과 동일한 유형 (cv-qualification 무시)으로핸들러([except.handle])의 em-exception-declaration은 복사/이동 작업이 될 수 있습니다. 자동 객체를 함수 호출의 반환 객체로 직접 구성하여 생략...