Error suggest parentheses around assignment used as truth value

Как исправить Warning? C++ Решение и ответ на вопрос 2182025

Terminator004

3 / 2 / 1

Регистрация: 14.09.2016

Сообщений: 501

1

30.01.2018, 03:03. Показов 15098. Ответов 5

Метки нет (Все метки)


Warning ругается на эту строчку:

C++
1
if(pasirinkimas = true)

И пишет: warning: suggest parentheses around assignment used as truth value [-Wparentheses]|
Что не так?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
    #include <iostream>
    #include <string>
    #include <conio.h>
 
    #include <cstdlib> 
    using namespace std;
 
    int main()
    {
        system("mode con cols=120 lines=40");
 
   int pasirinkimas;
    cout << "Выберите товар. Введите число: n 1 - лимонn 2 - чайn 3 - бананn 4 - кофеn 5 - ничегоn Ваш выбор: " ;
    cin >> pasirinkimas;
    switch(pasirinkimas)
    {
    case 1:
        cout << "лимон" << endl;
        break;
    case 2:
        cout << "чай" << endl;
        break;
    case 3:
        cout << "банан" << endl;
        break;
    case 4:
        cout << "кофе" << endl;
        break;
    case 5:
        cout << "ничего" << endl;
        break;
 
    default:
        cout << "Плохой выбор" << endl;
    }
 
if(pasirinkimas = true)
    {
        char testi;
        cout << "Продолжать работу программы? (t/n) ";
        cin >> testi;
        switch(testi)
        {
 
        case 't':
            cout << "К сожелению, у нас больше нет товаров." << endl;
            break;
        case 'n':
            cout << "Программа окончила работу" << endl;
            break;
        default:
            cout << "Плохой выбор" << endl;
        }
    }
getch();
return 0;
}

Добавлено через 1 минуту
Всё работает, но, мне просто этот варнинг не нравится и не знаю как правильнее написать, чтоб он не появлялся.

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



0



outoftime

║XLR8║

1212 / 909 / 270

Регистрация: 25.07.2009

Сообщений: 4,361

Записей в блоге: 5

30.01.2018, 03:26

2

Цитата
Сообщение от Terminator004
Посмотреть сообщение

warning: suggest parentheses around assignment used as truth value

Предупреждение: предполагается что скобки вокруг присвоения используются в качестве истинного значения.

C++
1
pasirinkimas = true

Это присвоение переменной, именно поэтому когда проверяешь что-то на равенство лучше пиши сначала константу а потом то с чем сравниваешь, тогда тебе явно выдаст ошибку что ты напартачил.

C++
1
if (true = pasirinkimas)

выдаст тебе другую ошибку которая исправляется заметой оператора присвоения на оператор сравнения = на ==.



0



TheCalligrapher

Вездепух

Эксперт CЭксперт С++

10435 / 5704 / 1553

Регистрация: 18.10.2014

Сообщений: 14,101

30.01.2018, 03:28

3

Цитата
Сообщение от Terminator004
Посмотреть сообщение

Что не так?

Вы действительно хотите безусловно присвоить переменной pasirinkimas значение true? Если да, то тогда для того, чтобы убрать warning, надо будет поставить дополнительные скобки в if:

C++
1
if((pasirinkimas = true))

Но тогда мне не понятно, зачем вам вообще понадобился этот if, если он всегда заведомо true.

Если же вы хотели сравнить pasirinkimas с true, то оператор сравнения в С++ — это ==, а не =. В этот случае, однако, не ясно, какой смысл вы вкладываете в это сравнение. У вас pasirinkimas — это 1, 2, 3 и т.д. С чего бы это вдруг вам сравнивать его с true?



0



Terminator004

3 / 2 / 1

Регистрация: 14.09.2016

Сообщений: 501

30.01.2018, 03:51

 [ТС]

4

Цитата
Сообщение от TheCalligrapher
Посмотреть сообщение

Вы действительно хотите безусловно присвоить переменной pasirinkimas значение true,

А что, подругому не будет работать вот это:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
char testi;
        cout << "Продолжать работу программы? (t/n) ";
        cin >> testi;
        switch(testi)
        {
 
        case 't':
            cout << "К сожелению, у нас больше нет товаров." << endl;
            break;
        case 'n':
            cout << "Программа окончила работу" << endl;
            break;
        default:
            cout << "Плохой выбор" << endl;
        }

Так я тут и проверю, если человек выбрал что-то из этого:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 switch(pasirinkimas)
    {
    case 1:
        cout << "лимон" << endl;
        break;
    case 2:
        cout << "чай" << endl;
        break;
    case 3:
        cout << "банан" << endl;
        break;
    case 4:
        cout << "кофе" << endl;
        break;
    case 5:
        cout << "ничего" << endl;
        break;
 
    default:
        cout << "Плохой выбор" << endl;
    }

Так тогда, должно задать вот эти вопросы:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 char testi;
        cout << "Продолжать работу программы? (t/n) ";
        cin >> testi;
        switch(testi)
        {
 
        case 't':
            cout << "К сожелению, у нас больше нет товаров." << endl;
            break;
        case 'n':
            cout << "Программа окончила работу" << endl;
            break;
        default:
            cout << "Плохой выбор" << endl;
        }



0



Вездепух

Эксперт CЭксперт С++

10435 / 5704 / 1553

Регистрация: 18.10.2014

Сообщений: 14,101

30.01.2018, 04:32

5

Цитата
Сообщение от Terminator004
Посмотреть сообщение

Так я тут и проверю, если человек выбрал что-то из этого:

Я в упор не вижу никакой связи между if(pasirinkimas = true) и проверкой «если человек выбрал что-то из этого». При чем здесь true вообще?

Условие этого if — всегда заведомо истинно. Как он может что-то «проверять»?



0



Bargos

12 / 12 / 3

Регистрация: 15.11.2017

Сообщений: 37

30.01.2018, 06:38

6

Вместо

C++
1
if(pasirinkimas = true)

Попробуйте хотя бы это:

C++
1
if (pasirinkimas >= 1 && pasirinkimas <= 5)

Тот факт, что переменная в switch имеет значение, не совпадающее ни с одним из блоков case, не является для программы поводом для выведения ошибки. Это не аварийная ситуация.



0



Today I finally write down some musings on two peripheral aspects of
compiler diagnostic design that I think are very important for certain kinds of warnings.
My first musing relates to fixits, and my second to suppression mechanisms.

What is a fixit?

Most C++ compilers these days don’t just tell you that a problem occurred
(like ed’s famous ? prompt),
and what the problem is (“expected identifier,” for example).
They’ll try to tell you how to fix the problem.

Compare GCC 4.1’s error messages with GCC 4.6’s. (Godbolt.)
For this input:

GCC 4.1 complains merely that you have put multiple types in one declaration.
GCC 4.6 more helpfully complains that it expected ';' after struct definition,
and points to the exact position where it believes a semicolon should be inserted.

GCC 7 goes even further, and suggests a fixit — a machine-readable “spellcheck suggestion”
that some IDEs are able to apply with a single click.

test.cpp:1:12: error: expected ';' after struct definition
 struct S {}
            ^
            ;

In medical terms, the compiler has gone from simply detecting the symptom
(“this declaration seems to contain two types, which isn’t valid C++”)
to producing a diagnosis of the disease (“I bet you forgot a semicolon somewhere”);
and a compiler that supports fixits is actually prescribing a treatment plan.
Each of these steps is a quantum leap beyond the previous one in terms of both user-friendliness
and implementation complexity.

What is a suppression mechanism?

Suppression mechanisms relate to compiler warnings, not compiler errors.
Consider the following snippet (Godbolt):

if (argc = 1)
    puts("hello");

Every mainstream compiler warns on this suspicious-looking code (GCC and Clang with -Wall; MSVC with -W4).
Here’s GCC’s diagnostic:

warning: suggest parentheses around assignment used as truth value [-Wparentheses]
    4 |     if (argc = 1)
      |         ~~~~~^~~

Notice that GCC doesn’t even bother to explain really what its diagnosis is;
it emits a passive-aggressive warning message that does nothing more than suggest how to
shut itself up!

The diagnosis, of course, is that frequently people mean to write if (argc == 1)
but their finger slips and they write if (argc = 1) instead, which unfortunately
is also valid C++ code. Every mainstream compiler has evolved the same way to deal with this:
if you really mean =, then you write an extra pair of parentheses around the expression, like so:

The extra pair of parentheses is what I’m calling a “suppression mechanism.”
It’s just an arbitrary way of silencing a warning diagnostic — telling the compiler
“no, I really meant to write this legal but unusual construct.”

Another well-known suppression mechanism is writing (void) in front of unused results
to silence -Wunused-value and -Wunused-result warnings (Godbolt):

[[nodiscard]] int foo();
void test(int x) {
    (void)x;
    (void)foo();
}

And a trivial suppression mechanism is implied by the name of the -Wparentheses warning:

warning: '&&' within '||' [-Wlogical-op-parentheses]
    return (a && b || c);
            ~~^~~~ ~~

Here the compiler just wants you to add a pair of parentheses to clarify the precedence for the reader.

Musing: A single fixit must preserve (actual) behavior or (likely) intent, but can’t do both

It’s easy for the programmer to “fix” diagnostics like -Wunused-result and -Wlogical-op-parentheses,
because they’re just asking the programmer to clarify intent that is already pretty clear:
Yes, I mean to discard this result. Yes, I mean to evaluate (a && b) || c.

The more interesting diagnostics are the ones where the compiler believes it has identified a mismatch
between the code’s actual behavior and the programmer’s intent. Our if (argc = 1) example
above was like that. A more realistic example might be something like

Here it is almost certain that the programmer intended to write

However, the literal behavior of the code as written is equivalent to

When the compiler suggests a fixit for this warning, it has to choose: Should we suggest the fix
that changes the behavior of the code to what you probably meant to type — the “spellcheck” option?
Or should we show how to silence the warning while preserving the existing code’s behavior — the
“Add To Dictionary” option, if you will? (Or, continuing our medical analogy, there’s the “treatment”
option and the “DNR” option.)

Showing just the “treatment” option puts the compiler in the awkward position of “recommending” that you change
the behavior of code that is, after all, perfectly legal C++ already; blindly applying the fixit to
working code might break that code. But showing just the “suppression” option might encourage a programmer to
blindly apply the fixit to broken code, thus leaving the bug in place but making it harder to detect
in the future.

For certain kinds of warnings, Clang shows both fixits. Two examples of this in Clang 10
are (Godbolt):

warning: using the result of an assignment as a condition without parentheses [-Wparentheses]
    if (x = foo())
        ~~^~~~~~~
note: place parentheses around the assignment to silence this warning
    if (x = foo())
          ^
        (        )
note: use '==' to turn this assignment into an equality comparison
     if (x = foo())
          ^
          ==

and

warning: & has lower precedence than !=; != will be evaluated first [-Wparentheses]
    return (foo() & mask != 0);
                  ^~~~~~~~~~~
note: place parentheses around the '!=' expression to silence this warning
    return (foo() & mask != 0);
                  ^
                    (        )
note: place parentheses around the & expression to evaluate it first
    return (foo() & mask != 0);
                  ^
            (           )

Notice that in both cases, Clang decides to print the “suppression” option first
and the “treatment” option second.
But sometimes Clang prints the “treatment” option first and the “suppression” option second:

warning: size argument in 'strncmp' call is a comparison [-Wmemsize-comparison]
    return strncmp(a, b, len < 0);
                         ~~~~^~~
note: did you mean to compare the result of 'strncmp' instead?
    return strncmp(a, b, len < 0);
           ^                    ~
                            )
note: explicitly cast the argument to size_t to silence this warning
    return strncmp(a, b, len < 0);
                         ^
                         (size_t)( )

and

warning: logical not is only applied to the left hand side of this comparison [-Wlogical-not-parentheses]
    return x == y && !x == z;
                     ^  ~~
note: add parentheses after the '!' to evaluate the comparison first
    return x == y && !x == z;
                     ^
                      (     )
note: add parentheses around left hand side expression to silence this warning
    return x == y && !x == z;
                     ^
                     ( )

Of course, there are many more cases where Clang emits only the “suppression” option
as a fixit, leaving the programmer to figure out the “treatment” on their own. (GCC 10.2
emits a fixit for only the last of these four examples; and it’s the “suppression” option.)

Even in the absence of any machine-readable fixits, the phrasing of the warning message
itself can induce the human reader to think in terms of suppression or in
terms of treatment. A warning message can be phrased as “Please confirm that you meant X”;
or “You did X; did you mean Y?”; or even as “Your attempt to do Y failed.”

Musing: Suppression mechanisms are about edit distance, and about signaling

Compiler warnings of the kind we’re discussing here are basically of the form
“You wrote X, but I think you meant Y.” This happens only when X and Y are
in some sense close together. Sometimes the “closeness” is semantic, not syntactic
(as when the programmer means to invoke copy elision but writes return std::move(x) instead).
But for our purposes today, let’s just think about syntactic closeness. You meant
to write Y, but a minor typographical slip caused you to write X. In the examples above,
the slips are things like “omit one =,” or “omit a pair of parens” or
“put < 0 inside the parens instead of outside.”

Take X=”equality-compare !a to b” and Y=”negate the sense of a == b.”
There are some pieces of code that clearly intend to express X, such as (!a)==(b).
There are some that clearly intend to express Y, such as a != b.
But you wrote (!a==b), which falls into a gray area: it’s not clear which of
X and Y you really intended to express.

The job of the compiler-diagnostic-developer is to create some separation between
the space of inputs that the compiler considers “clearly X”
and the space of inputs that the compiler considers “clearly Y.”
Essentially, we create an error-correcting code by deliberately increasing the
edit distance
between pairs of inequivalent C++ programs — deliberately increasing the number of keystrokes
the programmer would have to screw up in order to transform a working (and warning-free)
C++ program into an inequivalent broken (yet warning-free) C++ program.

Furthermore, in cases where Y is more commonly intended than X, it should be relatively easier
to write Y than X. In our example that’s true even at the core-language level: a != b is
already easier to write than !a == b. But when we increase the distance between X-space and Y-space,
we shrink X-space by more than we shrink Y-space. If you really intend to express !a == b, we’ll force you
to retreat all the way to (!a) == b. This is kind of analogous to the
signaling principle
in economics or evolutionary biology: Basically, if you want the compiler to accept your intent,
your code must adopt some cumbersome and frankly maladaptive ornamentation in order to prove
its worthiness to the compiler.

According to the prevailing theory of
sexual selection in the animal kingdom,
when a peahen is deciding whether to accept
a particular peacock, she uses his ornamental
tail as a proxy for his success. A peacock with a big
cumbersome tail must be healthy and successful, and thus a good mate for the peahen. A peacock
with an unremarkable tail won’t merit mating with.

When the C++ compiler is deciding whether to accept a particular program without complaint,
it uses certain ornamental syntactic flourishes as a proxy for the code’s intent.
A questionable snippet that adopts those flourishes — say, if ((argc = 1)) with an extra set
of parentheses, or (void)x;, or strncmp(a, b, size_t(len < 0))must be intentional,
and thus a good match for the compiler. A questionable snippet that lacks any flourishes — say,
if (argc = 1) or x; or strncmp(a, b, len < 0) — won’t merit suppressing the warning.


Here’s this musing’s payoff: When deciding whether to warn on a sketchy construct, it’s
tempting to encode absolute rules such as “Don’t warn on (argc = 1) if it’s surrounded by a pair of
parentheses.” But we should instead think in terms of relative rules — rules that compare the
“degree of ornamentation” of what the programmer actually wrote versus the “degree of ornamentation”
of the code they would have written without their (hypothetical) typo. Observe:

if ((argc == 1) || (argc = 2)) {
    puts("Wrong number of arguments");
}

As of September 2020, neither Clang nor GCC catches this single-character typo. They see that
the subexpression (argc = 2) is parenthesized, which suffices to suppress their warning.

I think what they should do is compare the program as written to the “typo-corrected” program

if ((argc == 1) || (argc == 2)) {
    puts("Wrong number of arguments");
}

That’s obviously a plausible and unremarkable program, so the likelihood is high that the programmer
did indeed typo = for ==.
If the programmer really wants to silence the warning in this case, I think the programmer should
be forced to write

if ((argc == 1) || ((argc = 2))) {
    puts("Wrong number of arguments");
}

Now the hypothetically “typo-corrected” program would be

if ((argc == 1) || ((argc == 2))) {
    puts("Wrong number of arguments");
}

which is remarkable and implausible — it’s clearly got an ornamental excess of parentheses!

To put this yet another way: The compiler should separate the space of acceptable programs into
“those that use = with a remarkably high number of parentheses” and “those that use == with
an unremarkable number of parentheses.” Then, for purposes of warning diagnostics,
the compiler should essentially treat = and == as synonymous; it can rely on the number
of parentheses to indicate the programmer’s intent.

x == 2;  // oops, likely meant x = 2
bool help1 = argc = 1;  // oops, likely meant argc == 1 because that would be reasonable
bool help2 = (argc = 1);  // oops, likely meant (argc == 1)
bool help3 = ((argc = 1));  // OK: clearly didn't mean ((argc == 1))
int i1 = (argc = 1) ? 1 : 2;  // oops, likely meant (argc == 1)
int i2 = ((argc = 1)) ? 1 : 2;  // OK: clearly didn't mean ((argc == 1))

As of September 2020, Clang 10.1 and GCC 10.2 don’t do very well on these test cases.


This post was inspired by the mailing-list thread
“[cfe-dev] parentheses flag warning”
(May 2020).

Очень часто начинающие программисты впадают в суеверный ужас, когда видят, что компилятор нашел в тексте программы ошибку, но не понимают, в чем она заключается.

А если помножить этот факт на незнание английского языка («чего там ему не нравится?..») и слабое владение синтаксисом C++ («хм, а может, тут нужна точка с запятой…»), то проблема принимает масштаб катастрофы.

Тот факт, что компилятор в силу своих ограниченных возможностей изо всех сил старается объяснить, что конкретно неверно, не спасает ситуацию. Как быть, если гуглить неохота, а спросить не у кого?

В этом посте на правах копипаста с последующим переводом, дополнениями и исправлениями приведу описание наиболее распространенных сообщений об ошибках и предупреждений компилятора. Неприятность кроется в том факте, что разные компиляторы ругаются на одинаковые ошибки по-разному, а некоторые даже не замечают то, что другие принимают за ошибку. Все зависит от совести разработчиков компилятора, даты его выпуска, и др.

В качестве компилятора возьмем g++, который, в частности, может использоваться в среде Code::Blocks. Версия gcc (куда входит g++) для ОС Windows зовется MinGW. По ходу я буду давать аналоги ошибок из лексикона русскоязычной Microsoft Visual C++.

Итак, частые ошибки:

undeclared identifier

1) Пример

doy.cpp: In function 'int main()':
doy.cpp:25: 'DayOfYear' undeclared (first use this function)
doy.cpp:25: (Each undeclared identifier is reported only once for each function it appears in.)
doy.cpp:25: parse error before ';' token

2) Смысл
Использован идентификатор DayOfYear, но компилятор не нашел его объявления. Он не знает, что такое DayOfYear.

3) Когда бывает

  • Вы забыли включить какой-то заголовочный файл (#include...)
  • Вы где-то ошиблись в написании идентификатора (при объявлении или использовании)
  • Вы вообще забыли, что эту переменную надо объявить

Попытавшись скомпилировать это в Microsoft Visual C++, вы увидите:

error C2065: DayOfYear: необъявленный идентификатор

cout undeclared

1) Пример

xyz.cpp: In function 'int main()':
xyz.cpp:6: 'cout' undeclared (first use this function)
xyz.cpp:6: (Each undeclared identifier is reported only once for each function it appears in.)

2) Смысл
Суперклассика. Без комментариев.

3) Когда бывает

  • Вы забыли включить <iostream>
  • Вы забыли написать using namespace std;

jump to case label

1) Пример

switch.cpp: In function 'int main()':
switch.cpp:14: jump to case label
switch.cpp:11: crosses initialization of 'int y'

2) Смысл
Смысл туманен

3) Когда бывает
Вы попытались объявить и инициализировать переменную (объект, указатель и т.п.) в метке case оператора выбора switch. Правилами C++ это запрещено.

В Microsoft Visual C++ эта ошибка зовется

error C2360: пропуск инициализации 'y' из-за метки 'case'

Выход: заключите операторы этого case’а в фигурные скобки {}.

multi-line string / unterminated string

1) Пример
Программка

#include <iostream>

using namespace std;

int main()
{
cout << "Bob is my buddy;
cout << "and so is Mary" << endl;
}

вызовет бурную реакцию компилятора:

string.cpp:7:12: warning: multi-line string literals are deprecated
string.cpp: In function 'int main()':
string.cpp:7: 'so' undeclared (first use this function)
string.cpp:7: (Each undeclared identifier is reported only once for each function it appears in.)
string.cpp:7: parse error before 'Mary'
string.cpp:8:28: warning: multi-line string literals are deprecated
string.cpp:8:28: missing terminating " character
string.cpp:7:12: possible start of unterminated string literal

2) Смысл
Компилятор думает, что мы хотим создать строковую константу с содержащимся в ней переносом строки, что-то типа

"Hello
world!"

что не поддерживается языком. Также делается предположение о том, что мы, возможно, забыли поставить кавычки в конце первой строки. Собственно, так оно и есть.

3) Когда бывает
Когда не соблюдается правильное количество и положение кавычек в строковых литералах. Надо быть внимательнее.

Microsoft Visual C++ со свойственной ему детской непосредственностью, отметит, что нельзя делать переносы в строках и возмутится, где точка с запятой:

error C2001: newline в константе
error C2146: синтаксическая ошибка: отсутствие ";" перед идентификатором "cout"

comparison between signed and unsigned integer expressions

1) Пример

xyz.cpp: In function 'int main()':
xyz.cpp:54: warning: comparison between signed and unsigned integer expressions

2) Смысл
Это — предупреждение компилятора, которое говорит о том, что мы пытаемся сравнить (==, и т.д.) целочисленное выражение (может принимать положительные, отрицательные значения и 0) и беззнаковое целочисленное выражение (может быть только положительным, либо 0).

3) Когда бывает
Собственно, тогда и бывает. Напомню, что тип int по умолчанию знаковый, а некоторые функции (например, vector::size()) возвращают unsigned int.
К примеру, следующий на первый взгляд безобидный код вызовет описываемое предупреждение:

for (int i = 0; i < grades.size(); i++)
{
// ...
}

Следует помнить, что в памяти знаковые и беззнаковые типы имеют разные внутренние представления, поэтому надо быть чертовски осторожными с указателями.

В Microsoft Visual C++ предупреждение выглядит так:

warning C4018: <: несоответствие типов со знаком и без знака

suggest parentheses around assignment used as truth value

1) Пример

xyz.cpp: In function `int main()':
xyz.cpp:54: warning: suggest parentheses around assignment used as truth value

2) Смысл
Тоже классика. Компилятор предполагает (и в 99% случаев прав), что вы по ошибке включили в скобки в качестве условия для if/while/for вместо условного выражения выражение присваивания.

3) Когда бывает
Чаще всего — в if‘ах, когда вместо "==" используется "="

if (length = maxLength)

вместо

if (length == maxLength)

Заминка в том, что это не ошибка, т.к. в скомпилированной программе (если мы проигнорируем предупреждение) выражение присваивания (которое возвращает значение правого аргумента) во всех случаях, кроме тех, когда оно вернет 0, будет преобразовано к true.

Ссылки для дальнейшего изучения
Ошибки построения Microsoft Visual C++
GCC Compiler error messages
GCC Warnings

P.S. Следует отметить, что кроме ошибок стадии компиляции встречаются (гораздо реже) ошибки препроцессора (например, если не найден заголовочный файл <iostram>), ошибки стадии компоновки (можно избежать, если научиться пользоваться средой программирования) и — самый гнусный тип ошибок! — ошибки стадии выполнения. Т.н. runtime error. С ними может справиться только голова программиста, вооруженная отладчиком.

  • Forum
  • Beginners
  • Need help with warning message

Need help with warning message

I get this warning
||=== Build: Debug in menu_1 (compiler: GNU GCC Compiler) ===|
C:UsersDesktopProjectsmenu_1main.c||In function ‘menu’:|
C:UsersDesktopProjectsmenu_1main.c|43|warning: suggest parentheses around assignment used as truth value [-Wparentheses]|
||=== Build finished: 0 error(s), 1 warning(s) (0 minute(s), 0 second(s)) ===|
while I try to compile?
The program works fine, but I wanna know why do I get this warning and how to fix it..

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <windows.h>

#define KEY_UP 72
#define KEY_DOWN 80
#define KEY_ENTER 13

#define ARRAYSIZE(sel) (sizeof(sel) / sizeof(sel[0]))

/** SELECT_END is the last highlighted choice in selections. */
#define SELECT_END 12

void clear();
void menu();
void selector(unsigned int select);
void hideCursor();

int main()
{
    hideCursor();
    menu();
    return 0;
}

void hideCursor()
{
    HANDLE consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
    CONSOLE_CURSOR_INFO info;
    info.dwSize = 100;
    info.bVisible = FALSE;
    SetConsoleCursorInfo(consoleHandle, &info);
}

void menu()
{
  int select = 0;
  int x;

  selector(select);

  while(x = getch())
  {
    if(x == 72)
    {
      select -= 2;
      if(select < 0)
        select = 0;
      selector(select);
    }
    else if(x == 80)
    {
      select += 2;
      if (select > SELECT_END)
        select = SELECT_END;
      selector(select);
    }
  }
}

void clear()
{
  system("cls");
}

void selector(unsigned int select)
{
  const char *selections[] =
  {
    "nnnnnt 1.   Input info          <",
    "nnnnnt 1. Input info",
    "t 2.   Retrieve info       <",
    "t 2. Retrieve info",
    "t 3.   Modify info         <",
    "t 3. Modify info",
    "t 4.   View info list      <",
    "t 4. View info list",
    "t 5.   Delete info         <",
    "t 5. Delete info",
    "t 6.   About the program   <",
    "t 6. About the program",
    "t 7.   Exit Data Base      <",
    "t 7. Exit Data Base",
  };
  unsigned int i;

  clear();

  for(i = 0; i < ARRAYSIZE(selections); i += 2)
  {
    if(i == select)
      printf ("%sn", selections[i]);
    else
      printf ("%sn", selections[i + 1]);
  }
}

Probably bc the above isn’t a conditional statement.

In this context, the code is OK. The compiler is seeing = in a conditional and thinks you’re made a mistake and that it should be == — which is not right in this case.

its hard to say if its a mistake or not bc as far as i can tell its just an endless loop. The only question I have is in which scenario does x = getch() become false? from what i gather from research that function pauses the program waiting for input similar to cin so either you’ll enter a key or sit there forever. once a key is entered it displays the menu either way. VS won’t even let me use that function. It complains and says use something else.

Ohh.. so if the code is Okay and I was thinking the same thing, if I put the «==» it gives me another warning at the next line that should be this if(x == 72), and if I change it to this if(x = 72) it says comparison between pointer and integer.

Now I am really confused :| Is there a way to write the code without the warning ?
Or it is normal that the compiler act like that, cause I’m not use to see these warnings, I like to write a code without errors or any warnings, when compiles.

Last edited on

For Windows it should be _getch(). To terminate, Alt-Gr then a character.

Last edited on

Ohh.. so if the code is Okay and I was thinking the same thing, if I put the «==» it gives me another warning at the next line that should be this if(x == 72), and if I change it to this if(x = 72) it says comparison between pointer and integer.

OK, first things first. What do you want it to be? An assignment? Or a comparison? The fact that you changed it from one to the other suggests that you’re not sure what you even want here.

From context, it looks like you want:

— line 43 to be an assignment, in which case

=

is correct

— lines 45 and 52 to be comparisons, so

==

is correct

EDIT: You haven’t answered markyrocks’ question:

in which scenario does x = getch() become false?

Last edited on

No Mike.. I do really know what I want… in my case YES is an assignment, and my question was why the compiler give me the warning

suggest parentheses around assignment used as truth value

and the fact is I did not change it yet, I only said.. if it was a comparison

it will give me another warning like

comparison between pointer and integer

I only want to know how can I modify this to NOT show me the warning.

Last edited on

I only want to know how can I modify this to NOT show me the warning.

1
2
3
4
5
  while (1)
    {
        x = getch();
  //do stuff...
    }

or do what Mikey said. Either way its an endless loop.

Last edited on

seeplus has already explained why you’re getting a warning.

To remove it, enclose the assignment in a second pair of parentheses.

Ahh okay okay… got it. Something like this.

And I got no warnings.. :)

Thanks again guys

Last edited on

Maybe not from your compiler, but you seem to have ignored the ones from posters here…

You mean seeplus ? Nope I didn’t.. But he didn’t say anything about:

MikeyBoy

To remove it, enclose the assignment in a second pair of parentheses.

He mention

For Windows it should be _getch(). To terminate, Alt-Gr then a character.

, and I use even _getch and doesn’t remove the warning.

Sorry markyrocks, if I didn’t give you an answer, I didn’t do this intentional , I guess I was posting only a part of code so you can’t see when x become false.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
...
...
#Define KEY_ENTER 13

void menu()
{
    int select = 0;
    int x;

    selector(select);

    while((x = getch()))
    {
        if(x == 72)
        {
            select -= 2;
            if(select < 0)
                select = SELECT_END - 1;
            selector(select);
        }
        else if(x == 80)
        {
            select += 2;
            if (select > SELECT_END)
                select = 0;
            selector(select);
        }
        else if(x == 13) // ENTER KEY change the 'x'
        {
            if(select <= 1)
            {
                inputData();
            }
            else if(select <= 2)
            {
                retrieveData();
            }
            else if(select <= 4)
            {
                modifyData();
            }
            else if(select <= 6)
            {
                viewInfo();
            }
            else if(select <= 8)
            {
                deleteData();
            }
            else if(select <= 10)
            {
                about();
            }
            else if(select <= 12)
            {
                printf("nnnnttt    Exiting Data Base");
                Sleep(1000);
                system("cls");
                exit(0);
            }
        }
    }
}

Pressing Up and Down arrows only yes it’s an endless loop, after you stop on one of the menu elements, and if you press Enter Key ‘x’ become false.

its your program i’m not that worried about it. I realize some programs need to run until the user does a specific action to end it. The point i’m trying to make is that if the condition never has the possibility to be false then what is the point of it even being in that spot? something like that is imo just a bad habit and will just make it harder to read and debug later. By all means do it however you want. I remember having a similar scenario years ago so i definitely understand how someone gets into that situation. The way i made sure i never ran into that particular problem again was to never assign variable values inside of a conditional statement. Part of my habit was coming from other languages that = could be a conditional operator and it would be interpreted that way if it was in a position where a conditional statement was supposed to be. In that scenario going

1
2
int x=NULL;
while(x=somefunc())  //would be false every time. 

obviously this doesn’t apply to c++

Topic archived. No new replies allowed.

AlfBaz

Super Member

  • Total Posts : 410
  • Reward points : 0
  • Joined: 2010/01/19 23:46:36
  • Location: Wollongong, Australia
  • Status: offline

Just wondering if anybody has encountered this before
I mistakenely wrote
if(UartMsg[1][0] = »)
instead of
if(UARTMsg[1][0] == »)

  and got

sourcemain.c:88: warning: suggest parentheses around assignment used as truth value

I don’t ever remeber seeing anything like this before and was curious as to its meaning… and I haven’t figured out where the parentheses go

forum member formerly known as izi

DarioG

Allmächtig.

  • Total Posts : 54081
  • Reward points : 0
  • Joined: 2006/02/25 08:58:22
  • Location: Oesterreich
  • Status: offline

Re:warning: suggest parentheses around assignment used as truth value


2010/07/01 06:38:46

(permalink)

I’ve seen it here & there, but did not care much Smile

«zealant» could be the right word for the compiler?

Deenayd

Super Member

  • Total Posts : 905
  • Reward points : 0
  • Joined: 2004/09/08 06:15:13
  • Location: Poland
  • Status: offline

Re:warning: suggest parentheses around assignment used as truth value


2010/07/01 06:42:00

(permalink)

Enter warning message into google and you’ll get your answer.

  The code you’ve written is correct, but is frequently a typo (assignment instead of comparision) and that’s why gcc gives you a warning.

  If you really want to use assignment as a truth value, you may enclose it in parentheses to get rid of the warning.

AlfBaz

Super Member

  • Total Posts : 410
  • Reward points : 0
  • Joined: 2010/01/19 23:46:36
  • Location: Wollongong, Australia
  • Status: offline

Re:warning: suggest parentheses around assignment used as truth value


2010/07/01 06:49:21

(permalink)

OK
From what I’ve googled it seems to be a warning for the typo = instead of ==
To supress you use double parentheses to tell the compiler its legitamate
if((UARTMsg[1][0] = »))
EDIT — Just seems a weird way to word it

forum member formerly known as izi

DarioG

Allmächtig.

  • Total Posts : 54081
  • Reward points : 0
  • Joined: 2006/02/25 08:58:22
  • Location: Oesterreich
  • Status: offline

Re:warning: suggest parentheses around assignment used as truth value


2010/07/01 11:22:30

(permalink)

thank you Deenayd Smile

Предупреждение компилятора — предлагайте скобки вокруг присваивания, используемого как значение истины

Когда я пытаюсь скомпилировать приведенный ниже фрагмент кода, я получаю следующее предупреждение:

warning: suggest parentheses around assignment used as truth value

Почему это происходит? Я считаю, что это довольно распространенная идиома. Я даже раньше использовал что-то подобное в своем коде.

struct PIDList* 
getRecordForPID(struct PIDList* list, pid_t pid) {
    while(list = list->next)
        if (list->pid == pid)
            return list;

    return NULL;
}

Будьте ясны — тогда компилятор не предупредит, что вы, возможно, допустили ошибку.

while ( (list = list->next) != NULL )

or

while ( (list = list->next) )

Когда-нибудь вы будете рады, что компилятор сказал вам, люди do совершите эту ошибку;)

ответ дан 29 мар ’11, в 18:03

Хотя эта конкретная идиома распространена, люди еще чаще используют = когда они имеют в виду ==. Соглашение, когда вы действительно имеете в виду = заключается в использовании дополнительного слоя круглых скобок:

while ((list = list->next)) { // yes, it's an assignment

ответ дан 29 мар ’11, в 18:03

Это просто предупреждение о безопасности. Это относительно распространенная идиома, но также и относительно частая ошибка, когда вы хотели == там. Вы можете убрать предупреждение, добавив еще один набор круглых скобок:

while ((list = list->next))

ответ дан 29 мар ’11, в 18:03

Не тот ответ, который вы ищете? Просмотрите другие вопросы с метками

c
compiler-construction
compiler-warnings

or задайте свой вопрос.

Понравилась статья? Поделить с друзьями:
  • Error subreport could not be shown перевод
  • Error subquery has too many columns
  • Error subprocess exited with error python
  • Error subprocess exited with error kivy
  • Error sub process usr bin dpkg returned error code 1 как исправить