c언어에서 자료형의 크기를 초과할 경우?

qkdlvlxk의 이미지

asd라는 타입의 최대 제한이 50이라고 했을 때 asd타입의 변수에 60이라는 수를 저장하고 출력했을 때 나오는 값은 쓰레기 값이라고 봐도 무방한가요??
예를 들면

asd 타입의 최대 값 : 50

asd val;
val = 60;
 
printf("%d", val);

이런 식일 때 뭐가 값이 출력되긴 하더라구요.
이럴 때 출력되는 값은 뭔가요??

HDNua의 이미지

출력되는 값은, 원래 저장 가능한 크기의 값만큼 되겠습니다.
예를 들어 1바이트는 unsigned 형식으로 0부터 255까지, 0000_0000부터 1111_1111까지 저장 가능한데
256 = 1_0000_0000을 저장하려고 하면 맨 앞의 1은 잘리고 0000_0000만 저장됩니다.

원래는 오버플로우 관련 답변을 달았었는데, 틀린 답변을 단 것 같아서 삭제했습니다.

저는 이렇게 생각했습니다.

qkdlvlxk의 이미지

감사합니다.

jick의 이미지

asd가 enum이라는 가정 하에, asd는 최대값인 50을 담을 수 있는 적당한 정수 type으로 간주됩니다. 요즘 사용하는 거의 모든 시스템에서 "50을 담을 수 있는 정수"는 60도 담을 수 있으므로 val = 60은 정상적으로 수행될 수 있습니다.

200은 좀 문제가 있을 수 있습니다. (asd가 signed char일 수도 있으므로...)

http://en.cppreference.com/w/c/language/enum

> Each enumerated type is compatible with one of: char, a signed integer type, or an unsigned integer type. It is implementation-defined which type is compatible with any given enumerated type, but whatever it is, it must be capable of representing all enumerator values of that enumeration.

qkdlvlxk의 이미지

아 혹시 적절한 타입으로 자동 형 변환이 된다는 뜻인가요??

jick의 이미지

형변환이라는 말은 좀 여기 쓰기엔 애매한 것 같군요. (무슨 타입에서 무슨 타입으로?)

좀 더 자세히 말하자면, C는 매우 저수준의 언어이기 때문에 enum을 만들어준다고 똑똑하게 "enum에서 적어준 값만 넣을 수 있는 변수" 같은 걸 만들어주지 않습니다. 예를 들어서

enum etype { RED=0, BLUE=1, GREEN=2 };

이렇게 적으면 etype이 "0, 1, 2만 들어갈 수 있는 타입"이 되는 게 아니라는 얘기죠. 대신 컴파일러가 알아서 적당히 "음 0, 1, 2는 반드시 들어갈 수 있어야 하니 무슨 타입이면 될까? int면 되겠네?" 하고, 비록 이름은 etype이지만 내부적으로는 적당한 크기의 정수형으로 구현해 줍니다. (이 "적당한 크기의 정수형"이 무엇인지는 implementation-defined이기 때문에 사용하는 OS나 컴파일러에 따라 바뀔 수 있습니다. 지금 테스트해보니 linux gcc/clang에서는 unsigned int를 쓰는군요. 다른 시스템에서는 더 작은 정수형을 쓸 수도 있습니다.)

그래서 다음과 같은 코드가 가능해집니다.

enum etype e = 5;

이건 "형변환"이라기보다는 그냥 원래 etype이 5까지 충분히 담을 수 있는 크기의 모종의 정수형으로 만들어져서 그 범위의 값을 담을 수 있는 거죠.

하지만 이런 식으로 코드를 짜는 것은 저라면 별로 권하지는 않겠는데 왜냐 하면 다음과 같은 골치아픈 에러가 생길 수 있기 때문이죠.

enum etype { RED=0, BLUE=1, GREEN=2 };
enum etype e;
e = -1;
 
printf("e = %d sizeof(e) = %zu\n", e, sizeof(e));
if (e > RED)
    printf("ERROR!\n");

이 코드는 제 컴퓨터에서 (linux x86-64 gcc) "ERROR!"를 출력합니다. 컴파일러가 etype을 unsigned int로 간주했기 때문이죠. enum의 정의에 0, 1, 2만 넣었기 때문에 컴파일러가 unsigned int를 사용하는 건 합법적입니다. (심지어 -W -Wall을 켜도 아무 경고도 안 뜹니다.)

GREEN을 -2로 바꿔주면 컴파일러가 더 이상 unsigned int를 쓸 수 없기 때문에 ERROR가 찍히지 않습니다.

qkdlvlxk의 이미지

아 감사합니다

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.