Note that there are some explanatory texts on larger screens.

plurals
  1. POStrange warning in a C function const multidimensional-array argument
    primarykey
    data
    text
    <p>I'm getting some strange warnings about this code:</p> <pre><code>typedef double mat4[4][4]; void mprod4(mat4 r, const mat4 a, const mat4 b) { /* yes, function is empty */ } int main() { mat4 mr, ma, mb; mprod4(mr, ma, mb); } </code></pre> <p><code>gcc</code> output as follows:</p> <pre><code>$ gcc -o test test.c test.c: In function 'main': test.c:13: warning: passing argument 2 of 'mprod4' from incompatible pointer type test.c:4: note: expected 'const double (*)[4]' but argument is of type 'double (*)[4]' test.c:13: warning: passing argument 3 of 'mprod4' from incompatible pointer type test.c:4: note: expected 'const double (*)[4]' but argument is of type 'double (*)[4]' </code></pre> <p>If I define the function as:</p> <pre><code>void mprod4(mat4 r, mat4 a, mat4 b) { } </code></pre> <p>Or defining matrices in main as:</p> <pre><code>mat4 mr; const mat4 ma; const mat4 mb; </code></pre> <p>Or call the function in main as:</p> <pre><code>mprod4(mr, (const double(*)[4])ma, (const double(*)[4])mb); </code></pre> <p>Or even defining <code>mat4</code> as:</p> <pre><code>typedef double mat4[16]; </code></pre> <p>Makes the warning go away. What is happening here? Am I doing something invalid?</p> <p>The gcc version is 4.4.3, if relevant.</p> <p>I also posted on gcc bugzilla: <a href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47143" rel="nofollow noreferrer">http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47143</a></p> <p>My current workaround is making ugly macros that cast stuff for me:</p> <pre><code>#ifndef _NO_UGLY_MATRIX_MACROS #define mprod4(r, a, b) mprod4(r, (const double(*)[4])a, (const double(*)[4])b) #endif </code></pre> <hr> <p>Answer from Joseph S. Myers on gcc bugzilla:</p> <blockquote> <p>Not a bug. The function parameters are of type "pointer to array[4] of const double" because const on an array type applies to the element type, recursively, and then the outermost array type, only, of a parameter of array type decays to a pointer, and the arguments passed are of type "pointer to array[4] of double" after array-to-pointer decay, and the only case where qualifiers are permitted to be added in assignment, argument passing etc. is qualifiers on the immediate pointer target, not those nested more deeply.</p> </blockquote> <p>Sounds pretty confusing to me, like the function expects:</p> <pre><code>pointer to array[4] of const doubles </code></pre> <p>and we are passing</p> <pre><code>pointer to const array[4] of doubles </code></pre> <p>intead.</p> <p>Or would it be the inverse? The warnings suggest that the function expects a:</p> <pre><code>const double (*)[4] </code></pre> <p>which seems to me more like a</p> <pre><code>pointer to const array[4] of doubles </code></pre> <p>I'm really confused with this answer. Could somebody who understands what he said clarify and exemplify?</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload