Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 

C# 3.0의 기본 인자(default parameter)가 .NET 1.1/2.0에서도 실행될까?

확인해 보면 될 문제입니다. ^^ 다음과 같이 기본 인자를 사용한 예제를 만들고,

using System;

class Program
{
    static void Main(string[] args)
    {
        Test();
    }

    public static void Test(int n = -1)
    {
        Console.WriteLine(n);
    }
}

컴파일 된 결과를 IL 코드로 보면, 기본 인자가 ".param ... " 구문으로 표현되는 것을 볼 수 있습니다.

.method public hidebysig static void Test([opt] int32 n) cil managed
{
    .param [1] = int32(-1)
    .maxstack 8
    L_0000: nop 
    L_0001: ldarg.0 
    L_0002: call void [mscorlib]System.Console::WriteLine(int32)
    L_0007: nop 
    L_0008: ret 
}

즉, 저 구문을 가진 IL 코드를 .NET 1.1 용 ilasm.exe로 컴파일해보면 될텐데요. 그래서 다음과 같이 ".param [1] = int32(-1)" 코드는 보존하면서 내용상 .NET 1.1과 맞지 않는 부분을 제거해봤습니다.


.assembly extern mscorlib
{
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         
  .ver 2:0:0:0   // 2.0.0.0으로 되어 있지만 그래도 .NET 1.1 ilasm.exe에서 오류가 발생하지 않습니다.
}

.assembly ConsoleApp1
{
  .custom instance void [mscorlib]System.Reflection.AssemblyCopyrightAttribute::.ctor(string) = ( 01 00 12 43 6F 70 79 72 69 67 68 74 20 C2 A9 20   // ...Copyright .. 
                                                                                                  20 32 30 31 34 00 00 )                            //  2014..
  .custom instance void [mscorlib]System.Reflection.AssemblyDescriptionAttribute::.ctor(string) = ( 01 00 00 00 00 ) 
  .custom instance void [mscorlib]System.Reflection.AssemblyConfigurationAttribute::.ctor(string) = ( 01 00 00 00 00 ) 
  .custom instance void [mscorlib]System.Reflection.AssemblyCompanyAttribute::.ctor(string) = ( 01 00 00 00 00 ) 
  .custom instance void [mscorlib]System.Reflection.AssemblyProductAttribute::.ctor(string) = ( 01 00 13 43 6F 6E 73 6F 6C 65 41 70 70 6C 69 63   // ...ConsoleApplic
                                                                                                61 74 69 6F 6E 31 00 00 )                         // ation1..
  .custom instance void [mscorlib]System.Reflection.AssemblyTitleAttribute::.ctor(string) = ( 01 00 13 43 6F 6E 73 6F 6C 65 41 70 70 6C 69 63   // ...ConsoleApplic
                                                                                              61 74 69 6F 6E 31 00 00 )                         // ation1..
  .custom instance void [mscorlib]System.Reflection.AssemblyTrademarkAttribute::.ctor(string) = ( 01 00 00 00 00 ) 
  .custom instance void [mscorlib]System.Runtime.InteropServices.ComVisibleAttribute::.ctor(bool) = ( 01 00 00 00 00 ) 
  .custom instance void [mscorlib]System.Runtime.InteropServices.GuidAttribute::.ctor(string) = ( 01 00 24 66 30 34 36 37 37 66 65 2D 61 38 32 65   // ..$f04677fe-a82e
                                                                                                  2D 34 66 33 38 2D 39 61 35 33 2D 38 38 63 62 31   // -4f38-9a53-88cb1
                                                                                                  61 39 36 37 37 34 61 00 00 )                      // a96774a..
  .custom instance void [mscorlib]System.Reflection.AssemblyFileVersionAttribute::.ctor(string) = ( 01 00 07 31 2E 30 2E 30 2E 30 00 00 )             // ...1.0.0.0..

  // --- The following custom attribute is added automatically, do not uncomment -------
  //  .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 07 01 00 00 00 00 ) 

  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) 
  .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx
                                                                                                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.
  .hash algorithm 0x00008004
  .ver 1:0:0:0
}

.module ConsoleApp1.exe
// MVID: {91066B88-B54D-43E0-8598-3BEDD98ADDA5}
.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) 
.imagebase 0x00400000
.file alignment 0x00000200


.subsystem 0x0003       // WINDOWS_CUI
.corflags 0x00000001    //  ILONLY
// Image base: 0x00E70000


// =============== CLASS MEMBERS DECLARATION ===================

.class private auto ansi beforefieldinit Program
       extends [mscorlib]System.Object
{
  .method private hidebysig static void  Main(string[] args) cil managed
  {
    .entrypoint
    // Code size       9 (0x9)
    .maxstack  8
    IL_0000:  nop
    IL_0001:  ldc.i4.m1
    IL_0002:  call       void Program::Test(int32)
    IL_0007:  nop
    IL_0008:  ret
  } // end of method Program::Main

  .method public hidebysig static void  Test([opt] int32 n) cil managed
  {
    .param [1] = int32(0xFFFFFFFF)   // 기본 인자 값 구문이 있습니다.
    // Code size       9 (0x9)
    .maxstack  8
    IL_0000:  nop
    IL_0001:  ldarg.0
    IL_0002:  call       void [mscorlib]System.Console::WriteLine(int32)
    IL_0007:  nop
    IL_0008:  ret
  } // end of method Program::Test

  .method public hidebysig specialname rtspecialname 
          instance void  .ctor() cil managed
  {
    // Code size       7 (0x7)
    .maxstack  8
    IL_0000:  ldarg.0
    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()
    IL_0006:  ret
  } // end of method Program::.ctor

} // end of class Program


// =============================================================

// *********** DISASSEMBLY COMPLETE ***********************
// WARNING: Created Win32 resource file test.res

이 파일을 test.il로 저장하고 .NET Framework 1.1만 설치된 PC에서 컴파일해 봤는데요.

D:\temp>ilasm test.il /output:test.exe

Microsoft (R) .NET Framework IL Assembler.  Version 1.1.4322.2307
Copyright (C) Microsoft Corporation 1998-2002. All rights reserved.
Assembling 'test.il' , no listing file, to EXE --> 'test.exe'
Source file is ANSI

Assembled method Program::Main
Assembled method Program::Test
Assembled method Program::.ctor
Creating PE file

Emitting members:
Global
Class 1 Methods: 3;
Resolving member refs: 1 -> 1 defs, 0 refs
Writing PE file
Operation completed successfully

C:\temp>dir
 Volume in drive C has no label.
 Volume Serial Number is 5C71-DD99

 Directory of C:\temp

2014-10-03  오전 10:26    <DIR>          .
2014-10-03  오전 10:26    <DIR>          ..
2014-10-03  오전 10:26             2,560 test.EXE
2014-10-03  오전 10:25             4,965 test.il
               2 File(s)          7,525 bytes
               2 Dir(s)  17,396,654,080 bytes free

C:\temp>test
-1

보시는 바와 같이 컴파일도 잘 되고 실행까지 정상동작합니다.

이것이 의미하는 바가 뭐냐면? 기본 인자 기능은 이미 .NET 1.1 초기부터 IL 코드에 구현되어 있었던 것입니다. 하지만, 문법적으로 C#에서는 3.0까지 와서야 비로소 지원하게 된 것이고.

즉, 닷넷 프레임워크는 꽤나 유연하게 디자인 되었던 것입니다. ^^




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]







[최초 등록일: ]
[최종 수정일: 10/3/2014]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 



2014-10-05 04시33분
[Lyn] 아마 C++문법에선 이미 쓰이고 있었으니 C++.net 지원하느라 그랫을거란 추측정도 해보고 갑니다 `-`
[guest]
2014-10-05 04시40분
Lyn님 멋진 의견이군요. ^^ 공감갑니다.
정성태
2014-10-05 04시54분
지금 확인해보니, 그 당시 Managed C++에서는 "C++ managed class"의 경우 기본 인자 정의를 메서드에 포함할 수 없었습니다. (컴파일 오류가 발생하네요. ^^)
정성태

... 31  32  33  34  35  36  37  [38]  39  40  41  42  43  44  45  ...
NoWriterDateCnt.TitleFile(s)
12696정성태7/6/20218312VC++: 146. 운영체제의 스레드 문맥 교환(Context Switch)을 유사하게 구현하는 방법파일 다운로드2
12695정성태7/3/20218353VC++: 145. C 언어의 setjmp/longjmp 기능을 Thread Context를 이용해 유사하게 구현하는 방법파일 다운로드1
12694정성태7/2/202110370Java: 24. Azure - Spring Boot 앱을 Java SE(Embedded Web Server)로 호스팅 시 로그 파일 남기는 방법 [1]
12693정성태6/30/20218048오류 유형: 731. Azure Web App Site Extension - Failed to install web app extension [...]. {1}
12692정성태6/30/20217968디버깅 기술: 180. Azure - Web App의 비정상 종료 시 남겨지는 로그 확인
12691정성태6/30/20218732개발 환경 구성: 573. 테스트 용도이지만 테스트에 적합하지 않은 Azure D1 공유(shared) 요금제
12690정성태6/28/20219583Java: 23. Azure - 자바(Java)로 만드는 Web App Service - Tomcat 호스팅
12689정성태6/25/202110194오류 유형: 730. Windows Forms 디자이너 - The class Form1 can be designed, but is not the first class in the file. [1]
12688정성태6/24/20219860.NET Framework: 1073. C# - JSON 역/직렬화 시 리플렉션 손실을 없애는 JsonSrcGen [2]파일 다운로드1
12687정성태6/22/20217781오류 유형: 729. Invalid data: Invalid artifact, java se app service only supports .jar artifact
12686정성태6/21/202110289Java: 22. Azure - 자바(Java)로 만드는 Web App Service - Java SE (Embedded Web Server) 호스팅
12685정성태6/21/202110523Java: 21. Azure Web App Service에 배포된 Java 프로세스의 메모리 및 힙(Heap) 덤프 뜨는 방법
12684정성태6/19/20218962오류 유형: 728. Visual Studio 2022부터 DTE.get_Properties 속성 접근 시 System.MissingMethodException 예외 발생
12683정성태6/18/202110438VS.NET IDE: 166. Visual Studio 2022 - Windows Forms 프로젝트의 x86 DLL 컨트롤이 Designer에서 오류가 발생하는 문제 [1]파일 다운로드1
12682정성태6/18/20218065VS.NET IDE: 165. Visual Studio 2022를 위한 Extension 마이그레이션
12681정성태6/18/20217420오류 유형: 727. .NET 2.0 ~ 3.5 + x64 환경에서 System.EnterpriseServices 참조 시 CS8012 경고
12680정성태6/18/20218562오류 유형: 726. python2.7.exe 실행 시 0xc000007b 오류
12679정성태6/18/20219073COM 개체 관련: 23. CoInitializeSecurity의 전역 설정을 재정의하는 CoSetProxyBlanket 함수 사용법파일 다운로드1
12678정성태6/17/20218279.NET Framework: 1072. C# - CoCreateInstance 관련 Inteop 오류 정리파일 다운로드1
12677정성태6/17/20219908VC++: 144. 역공학을 통한 lxssmanager.dll의 ILxssSession 사용법 분석파일 다운로드1
12676정성태6/16/20219810VC++: 143. ionescu007/lxss github repo에 공개된 lxssmanager.dll의 CLSID_LxssUserSession/IID_ILxssSession 사용법파일 다운로드1
12675정성태6/16/20217881Java: 20. maven package 명령어 결과물로 (war가 아닌) jar 생성 방법
12674정성태6/15/20218760VC++: 142. DEFINE_GUID 사용법
12673정성태6/15/20219888Java: 19. IntelliJ - 자바(Java)로 만드는 Web App을 Tomcat에서 실행하는 방법
12672정성태6/15/202111024오류 유형: 725. IntelliJ에서 Java webapp 실행 시 "Address localhost:1099 is already in use" 오류
12671정성태6/15/202117823오류 유형: 724. Tomcat 실행 시 Failed to initialize connector [Connector[HTTP/1.1-8080]] 오류
... 31  32  33  34  35  36  37  [38]  39  40  41  42  43  44  45  ...