Is * ++ * p an acceptable syntax?

In K & R Section 5.10, in their sample implementation of the grep -like function, the following lines exist:

 while (--argc > 0 && (*++argv)[0] == '-') while (c = *++argv[0]) 

Understanding the syntax was one of the most difficult things for me, and even a couple of weeks after looking at it, I still have to think very slowly in the syntax to figure it out. I compiled a program with this alternative syntax, but I'm not sure if the second line is valid. I have never seen * and ++ alternating this, but it makes sense to me, it compiles and runs. It also does not require brackets or parentheses, which is perhaps part of why it seems to me more understandable. I just read the statements in only one direction (from right to left) instead of bouncing back and forth on either side of the variable name.

 while (--argc > 0 && **++argv == '-') while (c = *++*argv) 
+4
source share
4 answers

Good for one, one way to get someone to read your code is to go huh?!?!?!

So, in terms of readability, no, you probably shouldn't write such code.

However, it is valid code and breaks like this:

 *(++(*p)) 

First, p dereferenced. Then it increases. Then it is played out again.


To make things worse, this line:

 while (c = *++*argv) 

has an assignment in a loop condition. So now you have two side effects to make your reader spin. YAY !!!

+9
source

Seems true to me. Of course, you should not read it from left to right, not in the way the C compiler parses the source code, but not how the C grammars work, as a rule, you should first find an object that will work (in this case, argv ), and then analyze the operators, often, as in this case, from the inside (of the object) to the outside. The actual rules for parsing (and reading) are, of course, more complicated.

R.S. And personally, I think this line of code is really not hard to understand (and I am not a C programming guru), so I donโ€™t think you should surround it with parentheses, as Mystical suggests. That would make the code very large if you know what I mean ...

+3
source

There is no ambiguity, even without knowledge of the rules of priority.

Both ++ and * are prefixes of unary operators; they can only be applied to the operand that follows them. The second * can only be applied to argv , from ++ to *argv and from the first * to ++*argv . So this is equivalent to *(++(*argv)) . There is no possible connection between the ++ and * priorities, which could mean something else.

This is not like something like *argv++ , which could possibly be either (*argv)++ or *(argv++) , and you should apply priority rules to determine which one (it * (argv + +) ", because postfix operators bind more tightly than unary operators prefix).

There is a limitation that ++ can only be applied to lvalue; since *argv is the value of l, which is not a problem.

+1
source

Is this code valid? Yes, but thatโ€™s not what you asked.

Is this code acceptable? It depends (acceptable to anyone?).

I would not find this acceptable - I would find it "harder to read than necessary" for several reasons.

First; many programmers must work with several different languages, potentially with different operator precedence rules. If your code looks like it relies on certain rules of a language operatorโ€™s priority (even if itโ€™s not), then people should stop and try to remember what rules apply to that language.

Secondly; different programmers have different skill levels. If you ever work in a large development team, you will find that the best programmers write code that everyone can understand, and the worst programmers write code that contains subtle errors that half the team cannot detect. Most C programmers should understand " *++*argv ", but a good programmer knows that a small number of "not very good" programmers will either not understand or take some time to figure this out.

Thirdly; Of all the different ways of writing something, you must choose the option that best reflects your intention. For this code, you are working with an array, and therefore it should look like you are going to work with an array (and not with a pointer). Note. For the same reason, " uint32_t foo = 0x00000002; " is better than " uint32_t foo = 0x02; ".

+1
source

Source: https://habr.com/ru/post/1387924/


All Articles