int a [] = {1,2,}; 이상한 쉼표가 허용되었습니다. 특별한 이유가 있습니까?


335

어쩌면 나는이 행성에서 왔지만 다음과 같은 구문 오류가 있어야합니다.

int a[] = {1,2,}; //extra comma in the end

그러나 그렇지 않습니다. 나는이 코드는 비주얼 스튜디오에서 컴파일 할 때 놀랐습니다,하지만 난 표준을 확인하고 그것이 지금까지 C ++ 규칙에 관한 한, 그래서 같이 MSVC 컴파일러를 신뢰하지 배운 되는 표준에 의해 허용뿐만 아니라. 나를 믿지 않으면 문법 규칙에 8.5.1을 볼 수 있습니다.

여기에 이미지 설명을 입력하십시오

이것이 왜 허용됩니까? 이것은 어리석은 쓸모없는 질문 일지 모르지만 왜 내가 묻는 지 이해하고 싶습니다. 그것이 일반적인 문법 규칙의 하위 사례라면 이해할 것입니다. 초기화 목록 끝에서 중복 쉼표를 허용하지 않기 위해 일반적인 문법을 더 어렵게하지 않기로 결정했습니다. 그러나 추가 쉼표는 명시 적으로 허용됩니다. 예를 들면, (함수 취하는 함수 호출 인수리스트의 끝에서 중복 쉼표가 허용되지 않는 ...) 정상 .

이 중복 쉼표가 명시 적으로 허용되는 특별한 이유가 있습니까?


10
모든 사람들 은 '새 줄을 쉽게 추가'하는 데 동의하는 것 같습니다. 그러나 언어 사양을 정의하는 사람들 은 실제로 그런 일을 걱정합니까? 그들이 실제로 이해한다면 ;다음 토큰이 분명 할 때 누락을 무시하지 않는 이유는 무엇입니까 ?
YetAnotherUser

35
@YetAnotherUser : 그렇습니다. 언어 설계자들은 그러한 것들을 고려합니다. 세미콜론을 삭제하도록 허용하면 훨씬 더 큰 영향을 미치며 언어의 많은 부분에서 매우 모호 할 수 있습니다 (C에서는 공백이 의미가 없음을 기억하십시오). 여분의 쉼표는이 경우 모호하지 않습니다. 여분의 세미콜론은 거의 모호하지 않으므로 허용됩니다. 모호한 경우 ( for()예 : 이후 ) 추가하면 컴파일러 경고가 발생합니다.
Rob Napier

5
@Tomalak : 인간 독자에게는 모호하며 종종 실수입니다. 그것이 경고를 던지는 이유입니다. 마찬가지로 if (x = 1)문법에서는 모호하지 않지만 인간에게는 매우 모호하므로 경고가 표시됩니다.
Rob Napier

12
@Rob : if예제도 모호하지 않습니다. 나는 "모호한"것이 당신이 생각하는 것을 의미한다고 생각하지 않습니다!
궤도에서 가벼움 경주

5
컴파일러가 우리를 보호하는 것이 유용한 데 동의하는 한 배열 선언의 후행 쉼표는 컴파일러가 우리를 보호하는 데 유용한 것이 아닙니다.
Rob Napier

답변:


436

소스 코드를 쉽게 생성하고 나중에 쉽게 확장 할 수있는 코드를 작성할 수 있습니다. 추가 항목을 추가하는 데 필요한 사항을 고려하십시오.

int a[] = {
   1,
   2,
   3
};

... 기존 라인에 쉼표를 추가해야 하고 새 줄을 추가합니다. 세 개 뒤에 이미 쉼표가있는 경우와 비교 하면됩니다. 마찬가지로 줄을 제거하려면 마지막 줄인지 걱정하지 않고 쉼표를 사용하지 않고 줄을 다시 정렬 할 수 있습니다. 기본적으로 그것은 라인을 처리하는 방식에 균일 성이 있음을 의미합니다.

이제 코드 생성에 대해 생각해보십시오. (의사 코드)와 같은 것 :

output("int a[] = {");
for (int i = 0; i < items.length; i++) {
    output("%s, ", items[i]);
}
output("};");

현재 쓰고있는 항목이 처음인지 마지막인지에 대해 걱정할 필요가 없습니다. 훨씬 간단합니다.


89
또한 VCS를 사용하는 경우 항목을 추가하거나 제거 할 때 한 줄만 변경되므로 두 버전 간의 "차이"가 더 깨끗합니다.
Kevin Panko

47
@ Néstor : 왜 "불행"인가? 단점은 무엇입니까? 언어의 작은 부분에 대한 코드 생성 (및 손쉬운 조작)이 일부 고려되었다고 해서 언어의 모든 결정에 대한 기본 동기가되어야한다는 의미는 아닙니다. 타입 추론, 세미콜론 제거 등은 언어에 영향을 미칩니다. IMO라는 잘못된 이분법을 설정하고 있습니다.
Jon Skeet

18
네스토르 @ 독단을 통해 실용주의의 승리가 있다는 : 왜해야 않는 완벽 한 가지 또는 전체 가 더 다른, 유용한 모두의 혼합물 일하기? 실제로 쉼표를 추가하여 실제로 어떻게 방해합니까? 이것은 어떤 의미에서든 당신을 방해 한 불일치입니까? 그렇지 않은 경우 끝에 쉼표를 허용하는 실질적인 이점 과 관련이없는 우아함을 평가하십시오 .
Jon Skeet

8
@Mrchief : 입력 속도 문제가 아닙니다. 항목을 복사, 제거 또는 재정렬 할 때 간단합니다. 어제 인생이 더 단순 해졌습니다. 어떤 단점과 함께, 이유 없는 인생을 더 쉽게 만들어? MS에게 손가락을 가리 키려고 할 때, 나는 이것이 마이크로 소프트가 존재하기 전부터 C에 있었다고 생각합니다. 당신은이 타당성이 이상해 보이지만 매일 수백 회사에 걸쳐 수천 명의 개발자들에게 이익이 될 것이라고 확신합니다. 컴파일러 작성자에게 도움이되는 것을 찾는 것보다 더 나은 설명입니까?
Jon Skeet

6
이것은 K & R C로했다
페루 치오

126

다음과 같이하면 유용합니다.

int a[] = {
  1,
  2,
  3, //You can delete this line and it's still valid
};

6
JavaScript는이 구문을 지원합니다 : var a = [1, 2,];, 내가 알고있는 대부분의 다른 언어들도 : ActionScript, Python, PHP.
Sean Fujiwara

14
@Sean IE JavaScript에서 구문 분석 오류가 발생하므로 조심하십시오!
Skilldrick

10
IE9에서는 그렇지 않습니다. 그러나 이상한 일을합니다 ... null 요소를 만듭니다. 나는 조심할 것이다.
Sean Fujiwara

5
@Sean 죄송합니다. 맞습니다. IE의 구문 분석 오류가 아니지만 에 추가 요소 세트 삽입됩니다 undefined.
Skilldrick

3
가장 실망스럽게 JSON은이 구문을 지원하지 않습니다.
Timmmm

38

개발자가 사용하기 편하다고 생각합니다.

int a[] = {
            1,
            2,
            2,
            2,
            2,
            2, /*line I could comment out easily without having to remove the previous comma*/
          }

또한 어떤 이유로 든 코드를 생성하는 도구가 있다면; 이 도구는 초기화의 마지막 항목인지 여부를 신경 쓸 필요가 없습니다.


32

나는 항상 추가 요소를 쉽게 추가 할 수 있다고 가정했습니다.

int a[] = {
            5,
            6,
          };

단순히 다음과 같이됩니다.

int a[] = { 
            5,
            6,
            7,
          };

나중에.


3
편집 속도를 약간 빠르게 만드는 것이 구문을 어지럽히는 좋은 이유라고 생각하지 않습니다. IMHO 이것은 또 다른 이상한 C ++ 기능입니다.
Giorgio

3
@Giorgio : 글쎄, 그것은 C에서 상속되었습니다. 그것은 원래의 언어 사양에 대한 감독 일 뿐이며, 유용한 부작용이 생길 수 있습니다.
Oliver Charlesworth

좋아, 나는 그것이 C에서 온다는 것을 몰랐다. 방금 Java에서도 허용되는지 확인했다. 그래도 이상한 느낌이 듭니다 : 내 직감에서 쉼표는 종결자가 아닌 구분 기호입니다. 또한 마지막 쉼표를 생략 할 수 있습니다. 그렇다면 터미네이터입니까, 세퍼레이터입니까, 아니면 둘 다입니까? 그러나이 기능을 사용할 수 있으며 알아두면 좋습니다.
Giorgio

11
@Giorgio-소스 코드는 기계가 아닌 인간을위한 것입니다. 단순한 전치 오류를 방지하기위한 이와 같은 작은 것들이 감독이 아니라 축복입니다. 참고로 PHP 및 ECMAScript (및 JavaScript 및 ActionScript)에서도 이러한 방식으로 작동하지만 JSON (JavaScript Object Notation)에서는 유효하지 않습니다 (예 : [1,2,3,]OK이지만 {a:1, b:2, c:3,}그렇지 않습니다).
릴리스 됨

1
@Groky : 내가 생각할수록 프로그래밍 언어의 구문은 가능한 한 간단하고 일관되어야하고 가능한 한 적은 예외가 있어야한다는 것을 확신한다. ). 목록에 항목을 추가 / 제거 할 때 하나 또는 두 개의 키 입력을 저장하면 (코딩에 소요되는 총 시간과 비교할 때 종종 그렇지는 않습니다) 명확하게 정의 된 구문이 있습니다.
Giorgio

21

줄을 쉽게 추가 / 제거 / 생성하는 것에 대해 모든 사람들이 말하는 것은 정확하지만이 구문이 빛나는 곳은 소스 파일을 병합 할 때입니다. 이 배열이 있다고 상상해보십시오.

int ints[] = {
    3,
    9
};

이 코드를 리포지토리에 체크인했다고 가정합니다.

그런 다음 친구가 편집하여 끝 부분에 추가합니다.

int ints[] = {
    3,
    9,
    12
};

그리고 처음에 추가하여 동시에 편집하십시오.

int ints[] = {
    1,
    3,
    9
};

의미 상 이러한 종류의 작업 (처음에 추가, 끝에 추가)은 완전히 안전하게 병합되어야하며 버전 관리 소프트웨어 (가 급히 git)가 자동 병합 될 수 있어야합니다. 슬프게도, 9 이후 버전에 쉼표가없고 친구가 있기 때문에 그렇지 않습니다. 반면, 원본 버전에 후행 9가 있으면 자동 병합 된 것입니다.

따라서 내 경험에 따르면, 목록이 여러 줄에 걸쳐 있으면 후행 쉼표를 사용하고 목록이 한 줄에 있으면 사용하지 마십시오.


15

후행 쉼표는 이전 버전과의 호환성을 위해 허용됩니다. 주로 자동 생성되는 많은 기존 코드가 있으며, 뒤에 쉼표가 있습니다. 마지막에 특별한 조건없이 루프를 작성하는 것이 더 쉽습니다. 예 :

for_each(my_inits.begin(), my_inits.end(),
[](const std::string& value) { std::cout << value << ",\n"; });

프로그래머에게는 실제로 이점이 없습니다.

추신 :이 방법으로 코드를 자동 생성하는 것이 더 쉽지만 실제로는 항상 쉼표를 넣지 않도록주의를 기울였으며 노력이 최소화되고 가독성이 향상되었으며 더 중요합니다. 코드를 한 번 작성하면 여러 번 읽습니다.


5
나는 완전히 동의하지 않는다. [제 의견은] 프로그래머가 배열의 내용을 바꾸고, 윌리-닐리 등을 주석 처리하는 것이 유리하기 때문에 C 이후 오랫동안 만들어진 많은 언어로의 길을 찾았습니다. 어리석은 전치 유발 구문 오류에 대해 걱정할 필요가 없습니다. 우리는 이미 충분히 스트레스를받지 않습니까?
릴리스 됨

12
@Dereleased-동일한 논리에 의해 후행 (무엇이든)을 허용해서는 안되는 이유, 마지막에 무엇이든 복사하여 붙여 넣기가 더 쉽고 코드 생성기를 작성하는 것이 더 쉬운 방법 int a = b + c +;또는 방법 if(a && b &&);. 이 문제는 사소하고 주관적이며, 이러한 경우 코드 리더에 가장 적합한 것을 항상 수행하는 것이 좋습니다.
Gene Bushuyev

1
@Gene Bushuyev : 맞습니다! 나는 종종 줄 끝에 연산자가있는 + 또는 &&로 긴 표현식을 가지고 있으며 물론 표현식의 마지막 피연산자를 제거하고 싶을 때 여분의 시간을 소비해야합니다. 이 쉼표 구문이 정말 이상하다고 생각합니다!
Giorgio

2
@GeneBushuyev-나는 그들에 동의하지 않습니다. 배열 등에서 후행 쉼표를 허용하는 것은 버그 제거 기능이며 프로그래머로서의 삶을 더 쉽게 만들어 주지만, 가독성을 높이기 위해 후행 AND (&&) 문, 플러스 및 기타 기타 연산자를 조건부에서 제거하는 조치를 취합니다. 진술. 그냥 못 생겼어, IMO
Sune Rasmussen

2
&&연산자 와 관련하여 때로는 if (true \n && b1 \n && b2)필요에 따라 줄을 추가하고 제거 할 수 있도록 조건부와 같은 작업을 수행 합니다.
Christian Mann

12

내가 아는 한 이것이 허용되는 이유 중 하나는 자동으로 코드를 생성하는 것이 간단해야하기 때문입니다. 마지막 요소에 대한 특별한 처리가 필요하지 않습니다.


11

배열이나 열거 형을 뱉어내는 코드 생성기를 더 쉽게 만듭니다.

상상해보십시오.

std::cout << "enum Items {\n";
for(Items::iterator i(items.begin()), j(items.end); i != j; ++i)
    std::cout << *i << ",\n";
std::cout << "};\n";

즉, 후행 쉼표를 뱉지 않기 위해 첫 번째 또는 마지막 항목을 특별하게 처리 할 필요가 없습니다.

예를 들어 코드 생성기가 Python으로 작성된 경우 str.join()함수 를 사용하여 후행 쉼표를 뱉는 것을 피할 수 있습니다.

print("enum Items {")
print(",\n".join(items))
print("}")

10

이 시간이 지나면 아무도 Annotated C ++ Reference Manual ( ARM ) 을 인용하지 않았으며 [dcl.init] 에 대해 다음 과 같이 강조합니다.

초기화에 대한 표기법이 너무 많지만 각각 특정 스타일의 용도로 사용되는 것 같습니다. = {initializer_list가 옵트} 표기법 C로부터 상속 된 데이터 구조 및 배열의 초기화에 잘 작용한다. [...]

비록 ARM 이 쓰여진 이래로 문법은 발전했지만, 기원은 남아있다.

C99의 이론적 근거 로 가서 왜 이것이 C에서 허용되는지 알 수 있습니다 .

K & R은 이니셜 라이저 목록의 끝에 이니셜 라이저에서 후행 쉼표를 허용합니다. 표준은 이니셜 라이저 목록에서 멤버를 추가하거나 삭제할 때 유연성을 제공하고 이러한 목록의 기계 생성을 단순화하므로이 구문을 유지했습니다 .


1
문헌에 의해 가장 많이 뒷받침되는 답변과이 기능의 진정한 출처를지지하십시오.
Marko

10

다른 답변에서 언급되지 않은 하나의 사용 사례, 가장 좋아하는 매크로가 있습니다.

int a [] = {
#ifdef A
    1, //this can be last if B and C is undefined
#endif
#ifdef B
    2,
#endif
#ifdef C
    3,
#endif
};

마지막으로 처리 ,할 매크로를 추가하는 것은 큰 고통입니다. 이 작은 구문 변경으로 관리하기는 쉽지 않습니다. 그리고 이것은 매우 제한된 전임자보다 Turing complete langue에서 일반적으로 수행하기가 훨씬 쉽기 때문에 기계 생성 코드보다 중요합니다.


7

실제로는 허용되지 않는 언어는 Javascript 뿐이며 수많은 문제를 일으 킵니다. 예를 들어 배열의 중간에서 줄을 복사하여 붙여 넣은 다음 끝에 붙여 넣은 다음 쉼표를 제거하지 않으면 IE 방문자가 사이트가 완전히 손상됩니다.

* 이론적으로는 허용되지만 Internet Explorer는 표준을 따르지 않고 오류로 취급합니다.


(단지입니다 마법의 길이 속성을 사용하여 객체) 오히려 이상한 어쨌든입니다 자바 스크립트의 "배열" var x = [,,,](IE <구를 제외하고,하지만 스펙은 법적 말한다) 법적
피터 C

ECMAScript 사양에 따르면 완벽하게 유효합니다. 이론적으로 그것은 상기 사양, 특히 여기에있는 사양의 일부에 따라 JavaScript를 구현하는 모든 브라우저에서 작동해야합니다 .
릴리스

1
불행히도 JavaScript는 대중을위한 앱을 만드는 것입니다. 따라서 아니요, ~ 50 % 사용자가 앱을 사용하는 데 문제가있을 때는 완벽하게 유효하지 않습니다. 그리고 만약 내가 내가 IE <9를 금지 할 수 있다면-너무 많은 시간 이 거기서 좋은 코드를 만드는데 소비하는데 ...
kgadek

@Dere : 예, 나는) = 내 대답에 많이했다
토마스 Bonini

@Dereleased Microsoft는 다른 사람들이 최소한 정신이 변하고 있다는 것을 준수하는 자체 사양과 명령을 발명했습니다.
Chris McGrath

7

기계 분석, 예를 들어 구문 분석 및 코드 생성이 더 쉽습니다. 일관성을 통한 수정, 주석 달기 및 시각적 우아함과 같은 인간에게는 더 쉽습니다.

C라고 가정하면 다음을 작성 하시겠습니까?

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    puts("Line 1");
    puts("Line 2");
    puts("Line 3");

    return EXIT_SUCCESS
}

아니요. 최종 진술은 오류 일뿐만 아니라 일관성이 없기 때문입니다. 그렇다면 왜 컬렉션과 동일합니까? 마지막 세미콜론과 쉼표를 생략 할 수있는 언어로도 커뮤니티는 보통 그것을 좋아하지 않습니다. 예를 들어, Perl 커뮤니티는 세미콜론을 생략하는 것을 좋아하지 않는 것 같습니다. 쉼표에도 적용됩니다.

여러 줄의 코드 블록에 세미콜론을 생략하지 않는 것과 같은 이유로 여러 줄 컬렉션에서 쉼표를 생략하지 마십시오. 언어가 허락하더라도 그렇게하지 않겠어요? 권리?


이를 허용하는 언어 (예 : 파스칼)가 있습니다. 즉, 다음 중에서 선택해야합니다. 터미네이터 (C) 또는 세퍼레이터 (파스칼)로 사용할 수 있습니다. ','와 동일합니다. ','가 종결 자이면 괜찮습니다. 그러나 {1, 2, 3}은 구문 오류 여야합니다.
Giorgio

6

그 이유는 사소한 것입니다. 라인을 쉽게 추가 / 제거 할 수 있습니다.

다음 코드를 상상해보십시오.

int a[] = {
   1,
   2,
   //3, // - not needed any more
};

이제 후행 쉼표를 추가하거나 제거하지 않고도 목록에 항목을 쉽게 추가 / 제거 할 수 있습니다.

다른 답변과 달리 목록을 생성하는 것이 쉬운 이유라고 생각하지 않습니다. 결국 코드가 마지막 (또는 첫 번째) 행을 특수하게 처리하는 것은 사소한 일입니다. 코드 생성기는 한 번 작성되어 여러 번 사용됩니다.


6

모든 줄이 같은 형식을 따를 수 있습니다. 첫째, 이것은 새로운 행을 쉽게 추가하고 버전 제어 시스템이 변경을 의미있게 추적하도록하고 코드를보다 쉽게 ​​분석 할 수있게합니다. 나는 기술적 인 이유를 생각할 수 없다.


5

이를 통해 긴 목록에서 요소를 이동하여 발생하는 실수로부터 보호 할 수 있습니다.

예를 들어, 이와 같은 코드가 있다고 가정 해 봅시다.

#include <iostream>
#include <string>
#include <cstddef>
#define ARRAY_SIZE(array) (sizeof(array) / sizeof *(array))
int main() {
    std::string messages[] = {
        "Stack Overflow",
        "Super User",
        "Server Fault"
    };
    size_t i;
    for (i = 0; i < ARRAY_SIZE(messages); i++) {
        std::cout << messages[i] << std::endl;
    }
}

스택 교환 사이트의 원래 3 부작을 보여 주므로 훌륭합니다.

Stack Overflow
Super User
Server Fault

그러나 한 가지 문제가 있습니다. 보시다시피이 웹 사이트의 바닥 글에는 슈퍼 유저 전의 서버 오류가 표시됩니다. 다른 사람이 알아 차리기 전에 수정하십시오.

#include <iostream>
#include <string>
#include <cstddef>
#define ARRAY_SIZE(array) (sizeof(array) / sizeof *(array))
int main() {
    std::string messages[] = {
        "Stack Overflow",
        "Server Fault"
        "Super User",
    };
    size_t i;
    for (i = 0; i < ARRAY_SIZE(messages); i++) {
        std::cout << messages[i] << std::endl;
    }
}

결국, 줄을 움직이는 것은 그렇게 어려울 수 없었습니까?

Stack Overflow
Server FaultSuper User

"Server FaultSuper User"라는 웹 사이트는 없지만 컴파일러에서 해당 웹 사이트가 있다고 주장합니다. 이제 문제는 C에 문자열 연결 기능이있어서 큰 따옴표로 묶인 두 개의 문자열을 작성하고 아무것도 사용하지 않고 연결할 수 있다는 것입니다.- 입니다.

이제 원래 배열에 쓸모없는 쉼표가 있으면 어떻게 될까요? 글쎄, 그 줄은 움직일 것이지만 그런 버그는 발생하지 않았을 것입니다. 콤마처럼 작은 것을 놓치기 쉽습니다. 모든 배열 요소 뒤에 쉼표를 넣는 것을 기억하면 그러한 버그는 발생할 수 없습니다. 당신은 당신이 쉼표가 문제의 원인을 찾을 것까지, 무언가를 디버깅 네 시간 낭비하고 싶지 않을 것이다 .


4

많은 것들과 마찬가지로, 배열 이니셜 라이저의 후행 쉼표는 C ++에서 C로 상속 된 것 중 하나입니다 (그리고 영원히 지원해야 할 것입니다). 여기놓인 것과 완전히 다른 견해"Deep C secrets" 책에 언급되어 있습니다. 있습니다.

두 개 이상의 "쉼표 역설"이있는 예를 보자.

char *available_resources[] = {
"color monitor"           ,
"big disk"                ,
"Cray"                      /* whoa! no comma! */
"on-line drawing routines",
"mouse"                   ,
"keyboard"                ,
"power cables"            , /* and what's this extra comma? */
};

우리는 읽고 :

... 최종 이니셜 라이저 뒤의 쉼표는 오타가 아니라 원주민 C에서 가져온 구문의 실수입니다 . 그것의 존재 또는 부재는 허용되지만 의미없습니다 . ANSI C의 이론적 근거에서 주장하는 정당화는 자동화 된 C 생성을보다 쉽게 ​​만든다는 것입니다. 열거 형 선언이나 단일 선언의 여러 변수 선언자와 같이 모든 쉼표로 구분 된 목록에서 후행 쉼표가 허용 된 경우 더 신뢰할 수 있습니다 . 그들은 아닙니다.

... 나에게 이것은 더 의미가 있습니다.


2
enum경우 쉼표에 대한 금지 는 다소 흥미 롭습니다. 왜냐하면 누락 된 쉼표가 가장 모호하지 않은 경우이기 때문입니다. 주어진 struct foo arr[] = {{1,2,3,4,5}, {3,4,5,6,7}, }; 언어가 할당 할 수있는 두 가지 의미있는 의미가 있습니다. 2 요소 배열을 작성하거나 마지막 항목에 기본값이있는 3 요소 배열을 작성하십시오. 만약 C가 나중에 해석을 받아 enum foo {moe, larry, curly, };
들였다면

1
... C가 합리적으로 의미가 부여되었지만 (그렇지 않은 경우) 쉼표를 무시할 의향이있는 경우 (이것은 그것을 금지하는 데 유리한 주장이 될 것입니다) 그것은 궁금합니다. ' 와 (과 ) enum foo {moe,,larry,curly,};사이의 숫자를 건너 뛰는 것으로 해석 되더라도 쉼표에 의미가없는 경우에는 쉼표를 처리하지 않더라도 일반적으로 후행 쉼표가 처리되는지 또는 무시되는지는 중요하지 않습니다. 중요한 것은 마지막 항목이 선언 된 유형의 최대 값인지 여부입니다.moelarry
supercat

1
... 마지막으로 할당 된 열거 값 다음에 발생하는 오버플로를 무시해야한다고 간단히 처리 할 수 ​​있습니다.
supercat

@supercat C #과 같은 언어가 있으며 언어를 개발할 때 IDE 기능과 통합을 고려하는 선험적 인 디자인 연구가 진행됩니다. C는이 언어들 중 하나가 아니었다.
Nikos Athanasiou

C #과 같은 언어를 사용하더라도 설계 목표를 변경하면 설계 불일치가 심각해집니다. 예를 들어, 언어는 컴파일하기 쉬운 언어를 갖는 목표와 반대되는 것으로 보였기 때문에 (기본 프레임 워크가 지원할 수 있음에도 불구하고) 일반적인 메소드 및 연산자에 대해 모든 형태의 리턴 유형 오버로드를 지원하지 않았습니다. 람다 평가에는 확인이 NP- 완전한 형식 유추 규칙이 포함됩니다. 새로운 메소드 / 운영자 오버로드 규칙을 추가하면 기존 코드가 손상 될 수 있습니다 (좋은 규칙은 그러한 위험을 최소화 할 수 있다고 생각하지만).
supercat

2

코드 생성 및 편집 용이성 외에도 구문 분석기를 구현하려는 경우이 유형의 문법이 더 단순하고 구현하기 쉽습니다. C #은 enum정의의 항목과 같이 쉼표로 구분 된 항목 목록이있는 여러 위치에서이 규칙을 따릅니다 .


1

한 줄만 추가하면되고 마지막 항목을 특별한 경우처럼 추가 할 필요가 없으므로 코드 생성이 쉬워집니다. 매크로를 사용하여 코드를 생성 할 때 특히 그렇습니다. 언어에서 매크로에 대한 필요성을 없애려고 노력했지만 매크로가 사용 가능 해짐에 따라 많은 언어가 함께 발전했습니다. 추가 쉼표를 사용하면 다음과 같은 매크로를 정의하고 사용할 수 있습니다.

#define LIST_BEGIN int a[] = {
#define LIST_ENTRY(x) x,
#define LIST_END };

용법:

LIST_BEGIN
   LIST_ENTRY(1)
   LIST_ENTRY(2)
LIST_END

매우 간단한 예이지만, 종종이 패턴은 디스패치, 메시지, 이벤트 또는 번역 맵 및 테이블과 같은 것을 정의하기 위해 매크로에서 사용됩니다. 마지막에 쉼표를 사용할 수없는 경우 다음과 같은 특별 항목이 필요합니다.

#define LIST_LAST_ENTRY(x) x

사용하기가 매우 어색합니다.


0

따라서 두 사람이 별도의 지점에있는 목록에 새 항목을 추가 할 때 Git은 행 단위로 작동하므로 변경 사항을 올바르게 병합 할 수 있습니다.


-4

지정된 길이가없는 배열을 사용하면 VC ++ 6.0에서 자동으로 길이를 식별 할 수 있으므로 "int a [] = {1,2,};"를 사용하면 a의 길이는 3이지만 마지막 길이는 ' t 초기화되었습니다 "cout <


이 표준에 맞지 않는 VC6의 버그입니까?
Thomson
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.