글 목록 보기

2016.06.20 21:58

Visual C++ C4503 Warning Fix

Lyn
조회 수 3824 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
#include <map>
 
using namespace std;
 
struct VeryLongClassNameType1
{
 
};
struct VeryLongClassNameType2
{
 
};
struct VeryLongClassNameType3
{
 
};
struct VeryLongClassNameType4
{
 
};
struct VeryLongClassNameType5
{
 
};
typedef map<VeryLongClassNameType1VeryLongClassNameType2LongNameStdMap;
typedef map<VeryLongClassNameType3LongNameStdMapLongNameStdMap2;
typedef map<VeryLongClassNameType4LongNameStdMap2LongNameStdMap3;
typedef map<VeryLongClassNameType5LongNameStdMap3LongNameStdMap4;
 
int main()
{	
	LongNameStdMap4 a;
}

 

위와 같은 코드를 빌드 하면 컴파일과 실행엔 문제가 없지만 C4503 Waring 이 뜹니다.

이 Warning 은 http://msdn.microsoft.com/query/dev14.query?appId=Dev14IDEF1&l=EN-US&k=k(C4503)&rd=true 에서 보다 시피, type명이 너무 길어서 짤릴 수 있다는 경고인데, 이 경우 나중에 크래시 덤프 등을 얻어서 처리할때 type 이 매칭 되지 않을 우려가 있습니다. 사실 4098 라는 type 길이는 충분했... 어야 했는데 template 가 겹치고 겹치면서(주로 Map을 겹쳐서 tree 형태의 자료구조를 구성 할 경우겠지만 ....) 의도하지 않게 긴 type 명을 가지게 되어 버리는 경우가 있습니다.

 

이 경우 위의 MSDN 링크 에서는 아래와 같은 방식의 다른 클래스로 한번 Wrapping 하는 해결책을 제시 하고 있습니다.

typedef map<VeryLongClassNameType1VeryLongClassNameType2LongNameStdMap;
typedef map<VeryLongClassNameType3LongNameStdMap_LongNameStdMap2;
struct LongNameStdMap2
{
	_LongNameStdMap2 Element;
};
typedef map<VeryLongClassNameType4LongNameStdMap2LongNameStdMap3;
typedef map<VeryLongClassNameType5LongNameStdMap3LongNameStdMap4;
struct NewClass
{
	LongNameStdMap4 Element;
};

이 경우 map 에 대한 접근이 a.Element.find() 처럼 한단계가 더 들어가게 됩니다... 만약 이름이 그 이상으로 길어서 2~3번 더 중간에 이름을 끊어 줘야 하는 경우, a.Element.Element.find() 와 같은 상황이 발생합니다. warning 을 제거하기 위해 의도와 다른 불편한 사용 방법을 강요받게 되는거지요. 이건 좋은 방법이라고 할 수 없습니다.

 

이럴때는 

typedef map<VeryLongClassNameType1VeryLongClassNameType2LongNameStdMap;
typedef map<VeryLongClassNameType3LongNameStdMap_LongNameStdMap2;
class LongNameStdMap2 : _LongNameStdMap2
{
 
};
typedef map<VeryLongClassNameType4LongNameStdMap2LongNameStdMap3;
typedef map<VeryLongClassNameType5LongNameStdMap3LongNameStdMap4;
class NewClass : LongNameStdMap4
{
 
};

 

처럼 public 상속을 해버리면 간단합니다... 그럼 일반적으로 map을 쓰는것과 전혀 다르지 않는 방법으로 코딩하면서 워닝만을 제거 할 수 있습니다.

TAG •
?

Lyn
조회 수 4587 추천 수 0 댓글 0
Atachment
첨부 '3'
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

예전 x86 시절에는 다양한 calling convention 이 있었습니다.

MS가 OS API 의 디폴트로 사용한 pascal 식 호출방식(__stdcall) 막상 언어로 파스칼을 쓰는 델파이가 파스칼식을 사용 하지 않고 사용하고 있던 fastcall, 그리고 c에서 사용하는 cdecl

 

이 각각의 호출 방식은 각각 장단점이 있었는데, pascal 식은 바이너리의 크기가 작아진다, fastcall 은 인자 전달에 레지스터를 사용 하므로 속도에 유리하다, cdecl 은 최적화 단계에서 스택 push ,pop 을 생략할 수 있으므로, 최적화에 유리하고 가변인지를 지원 할 수 있다는 장점이 있었습니다.

 

그러나 바야흐로 x64 시대, 컴파일러를 설계하는 사람들은 각각의 장점을 통합한 새로운 호출 방식을 만들게 되었습니다. 그 이후 calling convention 을 지정하는 모든 키워드는 x64 컴파일시에 무시되며, 그런거 신경 안써도 되는 평화로운 세월이 이어져 왔습니다.

 

그러나 시간이 흘러 CPU는 클럭경쟁의 시대가 막이 내리고, SMID 와 멀티코어의 시대로 넘어 왔는데... 당연히 CPU 제조사들은 새 SIMD 명령어를 추가 하기 시작 했고, 그에 맞춰 새 명령어용 레지스터가 추가 되었습니다. 그 시점에서 컴파일러 개발자들은 이렇게 생각 햇나 봅니다 "어? 레지스터가 놀고있네?" 라고. 그리하여 VS2013 이후부터는 __vectorcall 이라는 키워드가 추가되어, 더이상 x64 바이너리에서도 calling convention 을 무시 할 수 없게 되었습니다.

 

간단한 예제를 보겠습니다.

 

#include <cstdio>
#include <intrin.h>

__m256i func(double d1, double d2, double d3, double d4, __m256i f)
{
    printf("%f %f %f %f\n", d1, d2, d3, d4);

    printf("%lld %lld %lld %lld\n", 
        f.m256i_u64[0], f.m256i_u64[1], f.m256i_u64[2], f.m256i_u64[3]);

    return f;
}

int __cdecl main()
{
    __m256i f;

    for (int i = 0; i < 4; ++i)
    {
        f.m256i_u64[i] = i;
    }
    
    f = func(0.1, 0.2, 0.3, 0.4, f);

    return 0;
}

 

이코드를 빌드해서 실행 해 보면 다음과 같은 코드를 볼 수 있습니다.

vc1.PNG

 

 

그리고 함수의 프로토타입에 __vectorcall 을 추가하여

__m256i __vectorcall func(double d1, double d2, double d3, double d4, __m256i f)

와 같이 만든 후 다시 빌드 해 보겠습니다

 

 

 

vc2.PNG

 

차이가 보이시나요? 첫 줄에서 ymm4 라는 avx 레지스터가 추가적으로 함수 전달에 쓰이는 것을 볼 수 있습니다.
매번 __vectorcall 을 붙이기 싫다면 

vc3.PNG

 

옵션에서 조정 하거나, /Gv 플래그를 추가하여 사용 할 수도 있습니다.
단 /Gv 플래그를 켤 경우, main 은 항상 __cdecl 이어야 한다는 조건이 있으므로, 위 코드처럼 __cdecl 을 붙여주지 않으면 경고가 발생 할 것이니 조심하세요.

TAG •
?

Lyn
조회 수 4430 추천 수 0 댓글 0
Atachment
첨부 '1'
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

지인이 물어 온 김에 정리 해 둡니다.

 

결론부터 말하면 C++ 의 Lambda 의 Calling Convention 은 상황에 맞춰 "그때그때 다르다" 입니다.
 

기본적으로 cdecl(물론 VC++ 프로젝트 설정에서 옵션을 바꾸면 다른 것도 가능합니다) 멤버여야 한다면 thiscall 그렇지 않으면 대입 되는 함수 포인터의 type 에 따라서 결정됩니다.
즉 원하는 형태로 대입만 하면 거기에 맞춰 적절히 컴파일 됩니다.

 

lambda.png

 

외부에 callback 함수를 넘길 때 stdcall 로 선언해야 하는 경우가 꽤 되는데(특히 윈도우 API들) 이 때도 부담없이 Lambda 를 사용 할 수 있습니다.

 

단 아쉽게도 auto 와의 조합은 제공하지 않는데, 

 

auto __stdcall f1 = [](int num1, int num2, int num3) { printf("%d %d %d\n", num1, num2, num3); };

 

와 같은 문법은 경고를 내며 __stdcall 이 무시됩니다... 

TAG •
?

Lyn
조회 수 4419 추천 수 0 댓글 0
Atachment
첨부 '3'
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

After Update VS2015 Update 2, nuget has problem.

 

fix that

 

0. Visualstudio 2015 Run As Administrator(Importent!)

1. Open TOOLS -> Options -> Nuget Package Manager -> Package Source

 

01.PNG

 

2. Click Plus Button

 

3. Change Name to any name, and Source to https://api.nuget.org/v3/index.json

02.png

and Click Update

03.PNG

 

4. Retry use nuget package

 

5. Profit!

 

TAG •
?

Lyn
조회 수 3470 추천 수 0 댓글 0
Atachment
첨부 '1'
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

3월 28일 업데이트 된 364.72 버전 Geforce 드라이버에서는 Vulkan 이 공식 지원됩니다.

또한 vulkan 지원 정보를 간략히 볼 수 있는 SW인 vulkaninfo 가 같이 설치됩니다

 

vul.PNG

 

?

Lyn
조회 수 3982 추천 수 0 댓글 0
Atachment
첨부 '1'
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

ov.PNG

 

네 3번째는 OpenVPN GUI Client 입니다.

High DPI 지원을 하지 않아, 강제확장 기능이 없는 구버전의 OS에서는 읽을 수 없는 크기의 로그를 (....) Windows 10 에서는 흐릿하게 보이는 로그를 자랑 하고 있습니다.

 

역시 얘도 그다지 자주 볼 화면이 아니니 상관은 없지만 무신경한건 마찬가지죠

TAG •
?

Lyn
조회 수 2762 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

type in console : Diskperf -Y

 

restart task manager

?

Lyn
조회 수 3669 추천 수 0 댓글 0
Atachment
첨부 '1'
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

NF.PNG

 

두 번째는 네이버에서 배포하는 네이버 폰트 인스톨러입니다.

Uncode 지원을 하지 않아 박살나는 한글과, 역시 High DPI 지원을 하지 않아 흐릿하게 보이는 글씨를 볼 수 있습니다.

아무리 한국어OS 사용자가 사용할 가능성이 99%가 넘는다 해도 한국 최고의 IT 대기업 치고는 너무 무신경하네요.

TAG •
?

Lyn
조회 수 3510 추천 수 0 댓글 0
Atachment
첨부 '1'
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

WSM.PNG

 

첫 타자는 Windows Service 관리도구입니다.

MS의 OS 의 일부임에도 불구하고 이놈은 최신의 WIndows 10 에서 조차 HighDPI 에 대한 처리가 전혀 되어 있지 않습니다 (...)

아무리 일반인이 자주 보지 않는 프로그램이라곤 하지만 좀 MS의 무신경함은 좀 심하네요.

TAG •
?

?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

Windows 가 유니코드 기반의 OS가 된지 데스크탑 OS만 따지면 무려 15년, 기업용 워크스테이션 OS까지 따지면 그 이상이 지났고, High DPI 지원도 비슷한 시간을 보내 왔습니다.

 

그나마 High DPI 의 경우 꽤 오랜기간 96DPI 를 넘는 고해상도 장비가 나오지 않았으니 그나마 정상참작(?) 의 여지가 있긴 했지만 적어도 2016년 현재 시점에는 오히려 96DPI 해상도의 장비를 보기가 더 힘든 지경입니다(특히 모바일에서는)

 

하지만 MS Windows 는 그 이후 새로 나온 플랫폼도 아니고, OSX 처럼 레거시 API를 완전히 배제하여 호환성을 포기하지도 않은 덕분에, 아직까지도 이 두가지를 전혀 신경 쓰지 않은 어플리케이션이 꽤 많이 돌아다니고 있습니다. MS에서는 프로젝트 생성시 디폴트를 유니코드로 바꾸고, 심지어 최신의 VS에서는 아예 Non-Uncode 버전의 MFC 를 탑재하지 않는 강수를 두었음에도 궂이 프로젝트 옵션을 바꿔가면서까지 유니코드를 사용하지 않는 개발자들이 있습니다.

 

그래서 제발! Windows Application 의 퀄리티가 올라가길 바라는 심정으로, 이 두가지를 무신경하게 취급하는 SW 를 한번 정리 해 보고자 합니다.

 

단 아래와 같은 경우는 배제하겠습니다.

 

1. SW가 마지막 업데이트가 된지 3년이 넘은 구형 SW

 

 

전체목록 : 

http://lunapiece.net/Article/14007794 : 1. Windows Service Manager

http://lunapiece.net/Article/14007798 : 2. NAVER Font Installer

http://lunapiece.net/Article/14007820 : 3. OpenVPN GUI Client

TAG •
?

Board Pagination Prev 1 2 3 4 5 6 7 8 9 10 ... 13 Next
/ 13