c언어에서 이 경고 메세지는 뭔가요??

swr0920의 이미지

#include
void change(char *a, char *b);

int main()
{
char lt1[]="hello";
char lt2[15];

printf("hello\n");
change(lt1,lt2);
printf("lt1 = %s\n", lt1);
printf("lt2 = %s\n", lt2);

return 0;
}

void change(char *a, char *b)
{
while(*b++ = *a++);
}

/*이렇게 컴파일하면.... 경고메세지가 뜹니다...*/

hello.c:19:13: warning: using the result of an assignment as a condition without parentheses [-Wparentheses]
while(*b++ = *a++);
~~~~~^~~~~~
hello.c:19:13: note: place parentheses around the assignment to silence this warning
while(*b++ = *a++);
^
( )
hello.c:19:13: note: use '==' to turn this assignment into an equality comparison
while(*b++ = *a++);
^
==
1 warning generated.

hello
lt1 = hello
lt2 = hello

3번째꺼는 동일하다면 == 써다르는것 같은데 저걸 쓰면 비교 하게 되니 패쓰겠죠??
나머진 무슨 경고 메세지 인가요??

ymir의 이미지

= 는 assignment 이고 == 는 equality comparison 입니다.
assignment 는 always true 이기 때문에, 조건문에 while (a = b) 와 같은 식으로 쓰는 건 항상 true 가 됩니다. (무의미한 조건문이 되죠)
만약 a = b 하고나서 a 의 값(true or false)을 조건문으로 쓰려던거라면 while ((a = b)) 와 같이 괄호를 하나 더 써주면 되고..
만약 a 와 b 의 equality comparison 을 하려던 거라면 while (a == b) 와 같이 쓰라는 겁니다.

되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』

익명 사용자의 이미지

An assignment operator stores a value in the object designated by the left operand. An
assignment expression has the value of the left operand after the assignment, but is not an
lvalue. The type of an assignment expression is the type of the left operand unless the
left operand has qualified type, in which case it is the unqualified version of the type of
the left operand.

위 내용은 ISO/IEC 9899:TC3 문서의 Assignment operator 부분입니다.

극단적인 예로 a = 0 이라는 expression은 정수 0 이라는 값을 가지게 됩니다.
따라서 while (a = 0)는 while (0)이 되어 조건문을 평가할때 거짓이 되게 됩니다.

그리고 전 while ((a = b)) 와 같은 식은 본적이 없고 무의미한 식인거 같습니다. 혹시 다른 언어와 헛갈리신 건 아니신지요.

raymundo의 이미지

저게 무의미한 것은 맞지만, 실제로 gcc 에서는 (-Wall 또는 -Wparentheses 와 함께 써서) 괄호의 유무에 따라 경고가 나오네요. 저도 이 글을 보면서 처음 알았습니다만.

 warning: suggest parentheses around assignment used as truth value

프로그래머가 "==가 아니고 =를 쓰려는 거 맞음ㅇㅇ"라고 gcc에게 알려주는 효과가 있나봅니다. 아마도 i=j==k 형태의 코드에서 경고를 하려는 의도가 더 크지 않았을까 싶기도...

좋은 하루 되세요!

Anti-Lock의 이미지

그리고 전 while ((a = b)) 와 같은 식은 본적이 없고 무의미한 식인거 같습니다. 혹시 다른 언어와 헛갈리신 건 아니신지요.
while ((a=b))와 같은 코드는 사이드 이펙트를 고려하면 유의미 하지 않나요?
반복하는 동안 a는 b의 값을 복사해두며, b가 0이 되면 루프를 끝내는 거죠.
a는 다른 스레드가 감시하는 변수이거나, 하드웨어 레지스터일 수도 있구요.
형태가 조금 다르긴 하지만
while((*a++ = *b++)) 는 문자열 복사에서 주로 사용될법한 코드라고 생각됩니다.

raymundo의 이미지

위의 익명사용자님이 무의미하다고 말씀하신 건

while (a=b)
while ((a=b))

이 두 가지의 차이를 두고 말씀하신 거겠지요. (아닌가... ^^;;;)

좋은 하루 되세요!

익명 사용자의 이미지

반복하는 동안 a는 b의 값을 복사해두며, b가 0이 되면 루프를 끝내는 거죠.

혹시 말씀하신 동작이 while (a = 0) 과 wilhe ((a = 0)) 에서 다르게 작동하느지 여쭙고 싶습니다.

저도 괄호 관련 경고 메세지를 켜고 컴파일하면 경고가 나온다는 것을 처음 알았지만 저는 위 두 식의 차이는 그저 컴파일러를 위한 배려의 차이가 아닌가 생각합니다. (어쩌면 컴파일러의 프로그래머를 위한 배려에 대한 배려일 수도 있겠네요.)

ymir의 이미지

assignment 의 값에 따라 false 가 되는군요. 이 부분은 제가 착각하고 있었네요.
일단 (a=b) 처럼 그냥 써도 동작에는 무리가 없을 것으로 보입니다.

((a = b)) 처럼 쓰는 건, 조건문에 들어가는 의미를 좀 더 명확하게 하자는 거죠. (덤으로 warning 제거)
while ((a = b)) 는 while ((a = b) != 0) 와 문맥상 같습니다.

괄호 안 쓰고 기존의 문맥과 일치하도록 조건문을 다시 쓴다면, while (a=b) 는 while (a=b, a) 처럼 쓰면 되겠네요.

주: 그냥 관행처럼 별 생각없이 써오던거라 다시 설명하려고 보니, 잘못 알고 있던 부분이 많네요.
첫번째 답글은 설명이 틀린 부분이 많으니 무시해 주세요. 잘못된 답을 올려서 죄송합니다.

되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』

익명 사용자의 이미지

감사합니다^^

oosap의 이미지

kayws426 raymundo 님의 이야기다 다 맞는 것 같습니다.
저도 테스트까지 해봤는데 assignment 가 항상 true 인 건 아니었습니다.
프로그래머가 혹시 의도하지 않은 실수일 수도 있기에 코드상에서 모호한 부분이니 명확하게 괄호를 쓰라고 단지 경고하는 것이네요..

이런 경고도 맞춰주는게 정신건강에 이롭습니다. 컴파일러 옵션에서 워닝을 제거하기 보다는 코드상에서 이런 워닝에서 요구하는 내용을 지켜주는게 좋다는 의견입니다.

Thanks for being one of those who care for people and mankind.
I'd like to be one of those as well.

익명 사용자의 이미지

> 저도 테스트까지 해봤는데 assignment 가 항상 true 인 건 아니었습니다.

위에 익명님께서 인용하신 부분에 나와있기도 하지만, 확실하게 못을 박자면...

C에서 assignment operator의 결과값은 대입이 이루어지고 난 후의 좌항의 값인데, 그렇다고 lvalue인건 아닙니다.

An assignment expression has the value of the left operand after the assignment, but is not an lvalue.

C++은 조금 다른게, 좌항 그 자체의 값이고, lvalue입니다.

The result of the assignment operation is the value stored in the left operand after the assignment has taken place; the result is an lvalue.

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.