Welcome to Software Development on Codidact!
Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.
Post History
Reasons to use the construct #define FOO(x) do{...} while(0);: As mentioned above, doing so solves the problem of if (...) FOO(y); You can declare variables inside the block, and they ...
Answer
#9: Post edited
Reasons to use the construct> #define FOO(x) do{...} while(0);(1) as mentioned above, solves the problem of> if (...) FOO(y);(2) you can to declare variables inside the block, and they harmlessly go out of scope at the end of the block. Without the do{} block, the same symbol would cause a warning (or worse) if it were declared elsewhere in the block in which FOO(x) gets expanded.Why declare variables inside a macro? In case a macro argument appears more than once in the body, and someone writes FOO(func(y)), where func has side effects. This includes FOO(y++) etc. After the macro expands, the side effect would happen as many times as the macro argument appears in the body!Declaring a variable inside a do {} block prevents this, as follows:> #define FOO(x) do { long xx = x; func2(xx); func3(xx); } while (0);Obviously there is still an assumption about type of x, but that is the case anyway if you are going to be calling func2(x) etc(3) Without the do{} block, there might be ambiguity as to whether FOO(x) expands into a statement or an expression. do{} makes it clearly a statement, which can help catch someone trying to use FOO(x) where an expression is expected. See also: "statement-expressions", aka ({...}), which is a construct in case you want the block to be an expression rather than a statement.
- Reasons to use the construct `#define FOO(x) do{...} while(0);`:
- 1. As mentioned above, doing so solves the problem of
- ```
- if (...) FOO(y);
- ```
- 1. You can declare variables inside the block, and they harmlessly go out of scope at the end of the block. Without the `do{}` block, the same symbol would cause a warning (or worse) if it were declared elsewhere in the block in which `FOO(x)` gets expanded.
- Why declare variables inside a macro? In case a macro argument appears more than once in the body, and someone writes `FOO(func(y))`, where `func` has side effects. This includes `FOO(y++)` etc. After the macro expands, the side effect would happen as many times as the macro argument appears in the body!
- Declaring a variable inside a do {} block prevents this, as follows:
- ```
- #define FOO(x) do { long xx = x; func2(xx); func3(xx); } while (0);
- ```
- Obviously there is still an assumption about type of `x`, but that is the case anyway if you are going to be calling `func2(x)` etc.
- 1. Without the `do{}` block, there might be ambiguity as to whether `FOO(x)` expands into a statement or an expression. `do{}` makes it clearly a statement, which can help catch someone trying to use `FOO(x)` where an expression is expected. See also: "statement-expressions", aka `({...})`, which is a construct in case you want the block to be an expression rather than a statement.
#8: Post edited
- Reasons to use the construct
- > #define FOO(x) do{...} while(0);
- (1) as mentioned above, solves the problem of
- > if (...) FOO(y);
- (2) you can to declare variables inside the block, and they harmlessly go out of scope at the end of the block. Without the do{} block, the same symbol would cause a warning (or worse) if it were declared elsewhere in the block in which FOO(x) gets expanded.
Why declare variables inside a macro? In case a macro argument appears more than once in the body, and someone writes FOO(func(y)), where func has side effects. This includes FOO(y++) etc. After the macro expands, the side effect would happening multiple times.- Declaring a variable inside a do {} block prevents this, as follows:
- > #define FOO(x) do { long xx = x; func2(xx); func3(xx); } while (0);
- Obviously there is still an assumption about type of x, but that is the case anyway if you are going to be calling func2(x) etc
- (3) Without the do{} block, there might be ambiguity as to whether FOO(x) expands into a statement or an expression. do{} makes it clearly a statement, which can help catch someone trying to use FOO(x) where an expression is expected. See also: "statement-expressions", aka ({...}), which is a construct in case you want the block to be an expression rather than a statement.
- Reasons to use the construct
- > #define FOO(x) do{...} while(0);
- (1) as mentioned above, solves the problem of
- > if (...) FOO(y);
- (2) you can to declare variables inside the block, and they harmlessly go out of scope at the end of the block. Without the do{} block, the same symbol would cause a warning (or worse) if it were declared elsewhere in the block in which FOO(x) gets expanded.
- Why declare variables inside a macro? In case a macro argument appears more than once in the body, and someone writes FOO(func(y)), where func has side effects. This includes FOO(y++) etc. After the macro expands, the side effect would happen as many times as the macro argument appears in the body!
- Declaring a variable inside a do {} block prevents this, as follows:
- > #define FOO(x) do { long xx = x; func2(xx); func3(xx); } while (0);
- Obviously there is still an assumption about type of x, but that is the case anyway if you are going to be calling func2(x) etc
- (3) Without the do{} block, there might be ambiguity as to whether FOO(x) expands into a statement or an expression. do{} makes it clearly a statement, which can help catch someone trying to use FOO(x) where an expression is expected. See also: "statement-expressions", aka ({...}), which is a construct in case you want the block to be an expression rather than a statement.
#7: Post edited
- Reasons to use the construct
- > #define FOO(x) do{...} while(0);
- (1) as mentioned above, solves the problem of
- > if (...) FOO(y);
(2) you get to declare more variables inside the block, and they harmlessly go out of scope at the end of the block. Without the do{} block, the same symbol would cause a warning (or worse) if it were declared in the same block in which FOO(x) gets expanded.- Why declare variables inside a macro? In case a macro argument appears more than once in the body, and someone writes FOO(func(y)), where func has side effects. This includes FOO(y++) etc. After the macro expands, the side effect would happening multiple times.
- Declaring a variable inside a do {} block prevents this, as follows:
- > #define FOO(x) do { long xx = x; func2(xx); func3(xx); } while (0);
- Obviously there is still an assumption about type of x, but that is the case anyway if you are going to be calling func2(x) etc
- (3) Without the do{} block, there might be ambiguity as to whether FOO(x) expands into a statement or an expression. do{} makes it clearly a statement, which can help catch someone trying to use FOO(x) where an expression is expected. See also: "statement-expressions", aka ({...}), which is a construct in case you want the block to be an expression rather than a statement.
- Reasons to use the construct
- > #define FOO(x) do{...} while(0);
- (1) as mentioned above, solves the problem of
- > if (...) FOO(y);
- (2) you can to declare variables inside the block, and they harmlessly go out of scope at the end of the block. Without the do{} block, the same symbol would cause a warning (or worse) if it were declared elsewhere in the block in which FOO(x) gets expanded.
- Why declare variables inside a macro? In case a macro argument appears more than once in the body, and someone writes FOO(func(y)), where func has side effects. This includes FOO(y++) etc. After the macro expands, the side effect would happening multiple times.
- Declaring a variable inside a do {} block prevents this, as follows:
- > #define FOO(x) do { long xx = x; func2(xx); func3(xx); } while (0);
- Obviously there is still an assumption about type of x, but that is the case anyway if you are going to be calling func2(x) etc
- (3) Without the do{} block, there might be ambiguity as to whether FOO(x) expands into a statement or an expression. do{} makes it clearly a statement, which can help catch someone trying to use FOO(x) where an expression is expected. See also: "statement-expressions", aka ({...}), which is a construct in case you want the block to be an expression rather than a statement.
#6: Post edited
- Reasons to use the construct
- > #define FOO(x) do{...} while(0);
- (1) as mentioned above, solves the problem of
- > if (...) FOO(y);
- (2) you get to declare more variables inside the block, and they harmlessly go out of scope at the end of the block. Without the do{} block, the same symbol would cause a warning (or worse) if it were declared in the same block in which FOO(x) gets expanded.
Why declare variables inside a macro? In case someone writes FOO(y++). Or more generally FOO(func(y)) , where func has side effects.The do {} block is then used as follows:- > #define FOO(x) do { long xx = x; func2(xx); func3(xx); } while (0);
- Obviously there is still an assumption about type of x, but that is the case anyway if you are going to be calling func2(x) etc
- (3) Without the do{} block, there might be ambiguity as to whether FOO(x) expands into a statement or an expression. do{} makes it clearly a statement, which can help catch someone trying to use FOO(x) where an expression is expected. See also: "statement-expressions", aka ({...}), which is a construct in case you want the block to be an expression rather than a statement.
- Reasons to use the construct
- > #define FOO(x) do{...} while(0);
- (1) as mentioned above, solves the problem of
- > if (...) FOO(y);
- (2) you get to declare more variables inside the block, and they harmlessly go out of scope at the end of the block. Without the do{} block, the same symbol would cause a warning (or worse) if it were declared in the same block in which FOO(x) gets expanded.
- Why declare variables inside a macro? In case a macro argument appears more than once in the body, and someone writes FOO(func(y)), where func has side effects. This includes FOO(y++) etc. After the macro expands, the side effect would happening multiple times.
- Declaring a variable inside a do {} block prevents this, as follows:
- > #define FOO(x) do { long xx = x; func2(xx); func3(xx); } while (0);
- Obviously there is still an assumption about type of x, but that is the case anyway if you are going to be calling func2(x) etc
- (3) Without the do{} block, there might be ambiguity as to whether FOO(x) expands into a statement or an expression. do{} makes it clearly a statement, which can help catch someone trying to use FOO(x) where an expression is expected. See also: "statement-expressions", aka ({...}), which is a construct in case you want the block to be an expression rather than a statement.
#5: Post edited
- Reasons to use the construct
- > #define FOO(x) do{...} while(0);
- (1) as mentioned above, solves the problem of
> if (...) FOO(x);- (2) you get to declare more variables inside the block, and they harmlessly go out of scope at the end of the block. Without the do{} block, the same symbol would cause a warning (or worse) if it were declared in the same block in which FOO(x) gets expanded.
- Why declare variables inside a macro? In case someone writes FOO(y++). Or more generally FOO(func(y)) , where func has side effects.
- The do {} block is then used as follows:
- > #define FOO(x) do { long xx = x; func2(xx); func3(xx); } while (0);
- Obviously there is still an assumption about type of x, but that is the case anyway if you are going to be calling func2(x) etc
- (3) Without the do{} block, there might be ambiguity as to whether FOO(x) expands into a statement or an expression. do{} makes it clearly a statement, which can help catch someone trying to use FOO(x) where an expression is expected. See also: "statement-expressions", aka ({...}), which is a construct in case you want the block to be an expression rather than a statement.
- Reasons to use the construct
- > #define FOO(x) do{...} while(0);
- (1) as mentioned above, solves the problem of
- > if (...) FOO(y);
- (2) you get to declare more variables inside the block, and they harmlessly go out of scope at the end of the block. Without the do{} block, the same symbol would cause a warning (or worse) if it were declared in the same block in which FOO(x) gets expanded.
- Why declare variables inside a macro? In case someone writes FOO(y++). Or more generally FOO(func(y)) , where func has side effects.
- The do {} block is then used as follows:
- > #define FOO(x) do { long xx = x; func2(xx); func3(xx); } while (0);
- Obviously there is still an assumption about type of x, but that is the case anyway if you are going to be calling func2(x) etc
- (3) Without the do{} block, there might be ambiguity as to whether FOO(x) expands into a statement or an expression. do{} makes it clearly a statement, which can help catch someone trying to use FOO(x) where an expression is expected. See also: "statement-expressions", aka ({...}), which is a construct in case you want the block to be an expression rather than a statement.
#4: Post edited
- Reasons to use the construct
- > #define FOO(x) do{...} while(0);
- (1) as mentioned above, solves the problem of
- > if (...) FOO(x);
- (2) you get to declare more variables inside the block, and they harmlessly go out of scope at the end of the block. Without the do{} block, the same symbol would cause a warning (or worse) if it were declared in the same block in which FOO(x) gets expanded.
Why declare variables inside a macro? In case someone writes FOO(y++). Or more generally FOO(func1(y)) , where func1() has side effects. The do {} block is then used as follows:> #define FOO(x) do { long xx = x; func2(xx); func3(xx); }- Obviously there is still an assumption about type of x, but that is the case anyway if you are going to be calling func2(x) etc
- (3) Without the do{} block, there might be ambiguity as to whether FOO(x) expands into a statement or an expression. do{} makes it clearly a statement, which can help catch someone trying to use FOO(x) where an expression is expected. See also: "statement-expressions", aka ({...}), which is a construct in case you want the block to be an expression rather than a statement.
- Reasons to use the construct
- > #define FOO(x) do{...} while(0);
- (1) as mentioned above, solves the problem of
- > if (...) FOO(x);
- (2) you get to declare more variables inside the block, and they harmlessly go out of scope at the end of the block. Without the do{} block, the same symbol would cause a warning (or worse) if it were declared in the same block in which FOO(x) gets expanded.
- Why declare variables inside a macro? In case someone writes FOO(y++). Or more generally FOO(func(y)) , where func has side effects.
- The do {} block is then used as follows:
- > #define FOO(x) do { long xx = x; func2(xx); func3(xx); } while (0);
- Obviously there is still an assumption about type of x, but that is the case anyway if you are going to be calling func2(x) etc
- (3) Without the do{} block, there might be ambiguity as to whether FOO(x) expands into a statement or an expression. do{} makes it clearly a statement, which can help catch someone trying to use FOO(x) where an expression is expected. See also: "statement-expressions", aka ({...}), which is a construct in case you want the block to be an expression rather than a statement.
#3: Post edited
- Reasons to use the construct
- > #define FOO(x) do{...} while(0);
- (1) as mentioned above, solves the problem of
- > if (...) FOO(x);
(2) you get to declare more variables inside the block, and they harmlessly go out of scope at the end of the block. Without the do{} block, the same symbol would cause a warning (or worse) if it were declared in the same block in which FOO(x) gets expanded. Why declare variables inside a macro? To avoid unanticipated behavior for the caller due to macro argument getting expanded more than once. For example:> #define FOO(x) do { long xx = x; func1(xx); func2(xx); }Obviously there is still a type conversion issue, but that is the case just the same if you are going to be calling func1(x) etc(3) Without the do{} block, there might be ambiguity as to whether FOO(x) expands into a statement or an expression. do{} makes it clearly a statement, which can help catch someone trying to use FOO(x) where an expression is expected. See also: "statement-expressions", aka ({...}), which is mostly the same except the result is an expression rather than a statement.
- Reasons to use the construct
- > #define FOO(x) do{...} while(0);
- (1) as mentioned above, solves the problem of
- > if (...) FOO(x);
- (2) you get to declare more variables inside the block, and they harmlessly go out of scope at the end of the block. Without the do{} block, the same symbol would cause a warning (or worse) if it were declared in the same block in which FOO(x) gets expanded.
- Why declare variables inside a macro? In case someone writes FOO(y++). Or more generally FOO(func1(y)) , where func1() has side effects. The do {} block is then used as follows:
- > #define FOO(x) do { long xx = x; func2(xx); func3(xx); }
- Obviously there is still an assumption about type of x, but that is the case anyway if you are going to be calling func2(x) etc
- (3) Without the do{} block, there might be ambiguity as to whether FOO(x) expands into a statement or an expression. do{} makes it clearly a statement, which can help catch someone trying to use FOO(x) where an expression is expected. See also: "statement-expressions", aka ({...}), which is a construct in case you want the block to be an expression rather than a statement.
#2: Post edited
- Reasons to use the construct
- > #define FOO(x) do{...} while(0);
- (1) as mentioned above, solves the problem of
- > if (...) FOO(x);
(2) you get to declare more variables inside the block, and they harmlessly go out of scope at the end of the block. Without the do{} block, the same symbol would cause a warning (or worse) if it were declared in the same block in which FOO(x) gets expanded- (3) Without the do{} block, there might be ambiguity as to whether FOO(x) expands into a statement or an expression. do{} makes it clearly a statement, which can help catch someone trying to use FOO(x) where an expression is expected. See also: "statement-expressions", aka ({...}), which is mostly the same except the result is an expression rather than a statement.
- Reasons to use the construct
- > #define FOO(x) do{...} while(0);
- (1) as mentioned above, solves the problem of
- > if (...) FOO(x);
- (2) you get to declare more variables inside the block, and they harmlessly go out of scope at the end of the block. Without the do{} block, the same symbol would cause a warning (or worse) if it were declared in the same block in which FOO(x) gets expanded. Why declare variables inside a macro? To avoid unanticipated behavior for the caller due to macro argument getting expanded more than once. For example:
- > #define FOO(x) do { long xx = x; func1(xx); func2(xx); }
- Obviously there is still a type conversion issue, but that is the case just the same if you are going to be calling func1(x) etc
- (3) Without the do{} block, there might be ambiguity as to whether FOO(x) expands into a statement or an expression. do{} makes it clearly a statement, which can help catch someone trying to use FOO(x) where an expression is expected. See also: "statement-expressions", aka ({...}), which is mostly the same except the result is an expression rather than a statement.
#1: Initial revision
Reasons to use the construct > #define FOO(x) do{...} while(0); (1) as mentioned above, solves the problem of > if (...) FOO(x); (2) you get to declare more variables inside the block, and they harmlessly go out of scope at the end of the block. Without the do{} block, the same symbol would cause a warning (or worse) if it were declared in the same block in which FOO(x) gets expanded (3) Without the do{} block, there might be ambiguity as to whether FOO(x) expands into a statement or an expression. do{} makes it clearly a statement, which can help catch someone trying to use FOO(x) where an expression is expected. See also: "statement-expressions", aka ({...}), which is mostly the same except the result is an expression rather than a statement.