Don’t create generators with side effects:
import contextlib
@contextlib.contextmanager
def my_nice_context():
try:
print ' Before'
yield
finally:
print ' Afterwards'
def my_nice_contextualized_generator():
for x in ['a', 'b', 'c']:
with my_nice_context():
yield x
print "\nIterating my list as a generator, contextualizes the inner loop:"
for x in my_nice_contextualized_generator():
print ' X is %s' % x
print "\nBut this pattern is easy to break! Add list around it:"
for x in list(my_nice_contextualized_generator()):
print ' X is %s' % x
print "\nGenerators should not have side effects when they return values"
Because namespaces are implicit (consequence of ADL) using namespace should be in general be avoided, unless necessary such as to invoke ADL in a template function. (Niklaus Wirth took similar conclusion with module imports in Oberon07 and forced them to be explicit)
Defining a macro taking a body of code is a bad idea generally, as the compiler will eat away all the newlines and syntax errors will be emitted imprecisely as if they had happened in the initial line rather than precisely.
typedef struct Foo { } Foo;
People do this in C all the time because C otherwise requires you to always mention the type
struct Foo
rather than Foo
, however getting into that habit means forward declarations have
to be written:
typedef struct Foo Foo;
rather than simply struct Foo
I.e. the following is warning-free and valid:
enum AnEnum {
AnEnumValue,
};
enum AnotherEnum {
AnotherEnumValue,
};
int main(void) {
enum AnotherEnum value = AnEnumValue;
}
`int foo(void)` is what you want
Enums are of undefined signedness and size, and should not be used in library interfaces that aim for binary interface stability.
struct A
{
int a;
};
struct B
{
struct A super;
int b;
};
int main(int argc, char** argv)
{
(void)argc;
(void)argv;
// We want to zero-initialize without explicitely saying memset:
struct B test0 = {0}; // -wmissing-brace in -Wall
struct B test1 = {{0}}; // -wmissing-field-initializers in -Weverything
struct B test2 = {.b=0}; // only one that works without warning
return test0.super.a + test0.b +
test1.super.a + test1.b +
test2.super.a + test2.b;
}