As briefly discussed [in the comments on #1280](https://github.com/geany/geany/pull/1280/files/0d12919552f13940854c4a1162658...), this updates HACKING with some fairly common and widespread best practices.
Various links/references: https://www.securecoding.cert.org/confluence/display/c/DCL19-C.+Minimize+the... https://www.securecoding.cert.org/confluence/display/c/DCL00-C.+Const-qualif... http://wiki.c2.com/?DeclareVariablesAtFirstUse You can view, comment on, or merge this pull request online at:
https://github.com/geany/geany/pull/1282
-- Commit Summary --
* Update HACKING for best practices (C99)
-- File Changes --
M HACKING (14)
-- Patch Links --
https://github.com/geany/geany/pull/1282.patch https://github.com/geany/geany/pull/1282.diff
elextr commented on this pull request.
@@ -200,8 +200,18 @@ Coding
moment, we want to keep the minimum requirement for GTK at 2.24 (of course, you can use the GTK_CHECK_VERSION macro to protect code using later versions). -* Variables should be declared before statements. You can use - gcc's -Wdeclaration-after-statement to warn about this. +* Variables should be declared (and initialized) as close as practical
I suggest it says "(and initialized in the declaration)"
elextr commented on this pull request.
@@ -200,8 +200,18 @@ Coding
moment, we want to keep the minimum requirement for GTK at 2.24 (of course, you can use the GTK_CHECK_VERSION macro to protect code using later versions). -* Variables should be declared before statements. You can use - gcc's -Wdeclaration-after-statement to warn about this. +* Variables should be declared (and initialized) as close as practical + to their first use. This reduces the chances of intervening code being + inserted between declaration and use, where the variable may be + uninitialized. +* Variables should be defined within the smallest scope that is practical, + for example inside a conditional branch which uses them or in the + initialization part of a for loop. +* Local variables that will not be modified should be marked as ``const`` + to indicate intention. This allows the compiler to give a warning if + part of the code accidentally tries to change the value. This does not + apply to non-pointer parameters where it needlessly exposes the
Suggest that the fact that pointer params that do not change what is pointed to should be declared const is important enough for its own bullet point.
codebrainz commented on this pull request.
@@ -200,8 +200,18 @@ Coding
moment, we want to keep the minimum requirement for GTK at 2.24 (of course, you can use the GTK_CHECK_VERSION macro to protect code using later versions). -* Variables should be declared before statements. You can use - gcc's -Wdeclaration-after-statement to warn about this. +* Variables should be declared (and initialized) as close as practical + to their first use. This reduces the chances of intervening code being + inserted between declaration and use, where the variable may be + uninitialized. +* Variables should be defined within the smallest scope that is practical, + for example inside a conditional branch which uses them or in the + initialization part of a for loop. +* Local variables that will not be modified should be marked as ``const`` + to indicate intention. This allows the compiler to give a warning if + part of the code accidentally tries to change the value. This does not + apply to non-pointer parameters where it needlessly exposes the
Agree
b4n commented on this pull request.
@@ -200,8 +200,18 @@ Coding
moment, we want to keep the minimum requirement for GTK at 2.24 (of course, you can use the GTK_CHECK_VERSION macro to protect code using later versions). -* Variables should be declared before statements. You can use - gcc's -Wdeclaration-after-statement to warn about this. +* Variables should be declared (and initialized) as close as practical + to their first use. This reduces the chances of intervening code being + inserted between declaration and use, where the variable may be + uninitialized. +* Variables should be defined within the smallest scope that is practical, + for example inside a conditional branch which uses them or in the + initialization part of a for loop. +* Local variables that will not be modified should be marked as ``const`` + to indicate intention. This allows the compiler to give a warning if + part of the code accidentally tries to change the value. This does not + apply to non-pointer parameters where it needlessly exposes the + implementation and it's obvious a copy is made anyway.
It doesn't have to expose it, adding the `const` qualifier to an argument so that the argument itself is not modifiable still is compatible with a prototype not specifying it. ISO/IEC 9899:201x n1570 6.7.6.3§15 states that
[…] the parameter type lists, if both are present, shall agree in the number of parameters and in use of the ellipsis terminator; **corresponding parameters shall have compatible types**. […] (In the determination of type compatibility and of a composite type, each parameter declared with function or array type is taken as having the adjusted type and **each parameter declared with qualified type is taken as having the unqualified version of its declared type**.)
So it's perfectly valid to have ```C int foo(int); /* ... */ int foo(const int a) { return a; } ``` And qualifying the argument "variable" `const` is just as useful as for a local variable, or maybe even more as the value is likely not to be recoverable another way. We probably have very few of those in Geany's code, but there's a fair share in CTags and IMO it's a nice use of `const` just like on variables.
b4n commented on this pull request.
@@ -200,8 +200,18 @@ Coding
moment, we want to keep the minimum requirement for GTK at 2.24 (of course, you can use the GTK_CHECK_VERSION macro to protect code using later versions). -* Variables should be declared before statements. You can use - gcc's -Wdeclaration-after-statement to warn about this. +* Variables should be declared (and initialized) as close as practical + to their first use. This reduces the chances of intervening code being + inserted between declaration and use, where the variable may be + uninitialized. +* Variables should be defined within the smallest scope that is practical, + for example inside a conditional branch which uses them or in the + initialization part of a for loop. +* Local variables that will not be modified should be marked as ``const`` + to indicate intention. This allows the compiler to give a warning if + part of the code accidentally tries to change the value. This does not + apply to non-pointer parameters where it needlessly exposes the
Agreed, pointers should always be `const` unless the intention is to modify the pointed data.
codebrainz commented on this pull request.
@@ -200,8 +200,18 @@ Coding
moment, we want to keep the minimum requirement for GTK at 2.24 (of course, you can use the GTK_CHECK_VERSION macro to protect code using later versions). -* Variables should be declared before statements. You can use - gcc's -Wdeclaration-after-statement to warn about this. +* Variables should be declared (and initialized) as close as practical + to their first use. This reduces the chances of intervening code being + inserted between declaration and use, where the variable may be + uninitialized. +* Variables should be defined within the smallest scope that is practical, + for example inside a conditional branch which uses them or in the + initialization part of a for loop. +* Local variables that will not be modified should be marked as ``const`` + to indicate intention. This allows the compiler to give a warning if + part of the code accidentally tries to change the value. This does not + apply to non-pointer parameters where it needlessly exposes the + implementation and it's obvious a copy is made anyway.
I don't think it's a horrible idea, just that from the caller's point of view it's completely pointless, and it adds a lot of noise (ie. syntax) to nearly every single function. IMO, it's worth the trade-off to avoid it and use a separate `const` local initialized to the parameter's value if you really need to ensure it's not changed for some reason.
@codebrainz pushed 1 commit.
8354615 Fixups
Basically agree, the specific comments just add emphasis to a couple of points.
I updated it to move `const` on parameters to a new point as suggested. I removed the explicit note about not making value/non-pointer params `const`, let it be used if it's useful in a particular function, IMO.
@codebrainz yeah leaving this out is fine by me. So, LGTM, not sure if the remaining comment from @elextr is really useful as I feel that declaring late obviously implies that the initialization part has to be done there too, but I'm not against @elextr's wording either.
I didn't incorporate it because initialization can only happen in the declaration so I feel it's clear enough.
@codebrainz pushed 1 commit.
5e1c043 Add note about data types to HACKING
As discussed with @b4n on IRC, added a note about using better types.
codebrainz commented on this pull request.
- Don't let variable names shadow outer variables - use gcc's -Wshadow
option. +* Use the strictest possible data type where practical. For example
s/strictest possible/most semantically meaningful/
With your comment the new stuff looks ok.
The first comment is just to make it clearer for non-english is a first language people, not a required change.
Closed #1282 via fd38a49b55d7a4bfdb98069ac3bc839bf49d803b.
github-comments@lists.geany.org