Referencing a yet-to-be-mentioned function parameter using the new-style function declarationsHow do you pass a function as a parameter in C?Old style C function declarationIs there a general-purpose printf-ish routine defined in any C standarderror in running a simple C code in visual studioWhy does a function with no parameters (compared to the actual function definition) compile?Why does omitting explicit 'int' type for a parameter fail to compile in gcc sometimes?Why is the syntax “int (*)[*]” necessary in C?C++ Calling function inside another function that uses references and parametersC Function accepting value even when it's parameter is voidWhat happens when you declare a callback with wrong amount of parameters in C?

Can authors email you PDFs of their textbook for free?

'spazieren' - walking in a silly and affected manner?

Should a TA point out a professor's mistake while attending their lecture?

Doubt about a particular point of view on how to do character creation

How does the search space affect the speed of an ILP solver?

Does using composite keys violate 2NF

What caused the end of cybernetic implants?

Don't look at what I did there

My colleague treats me like he's my boss, yet we're on the same level

Why do motor drives have multiple bus capacitors of small value capacitance instead of a single bus capacitor of large value?

Heavy Box Stacking

Why 50 Ω termination results in less noise than 1 MΩ termination on the scope reading?

How to load files as a quickfix window at start-up

I was given someone else's visa, stamped in my passport

How smart contract transactions work?

Why does the U.S. military maintain their own weather satellites?

Welche normative Autorität hat der Duden? / What's the normative authority of the Duden?

Can UV radiation be safe for the skin?

Ideas behind the 8.Bd3 line in the 4.Ng5 Two Knights Defense

How were US credit cards verified in-store in the 1980's?

What is the practical impact of using System.Random which is not cryptographically random?

When you have to wait for a short time

Able To Save This Tree

An idiom for “Until you punish the offender, they will not give up offenses”



Referencing a yet-to-be-mentioned function parameter using the new-style function declarations


How do you pass a function as a parameter in C?Old style C function declarationIs there a general-purpose printf-ish routine defined in any C standarderror in running a simple C code in visual studioWhy does a function with no parameters (compared to the actual function definition) compile?Why does omitting explicit 'int' type for a parameter fail to compile in gcc sometimes?Why is the syntax “int (*)[*]” necessary in C?C++ Calling function inside another function that uses references and parametersC Function accepting value even when it's parameter is voidWhat happens when you declare a callback with wrong amount of parameters in C?






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








1















Compelled to use the variable length array feature for my auxiliary function that prints square matrices, I defined it as follows:



void print_matrix(M, dim)
unsigned dim;
int M[dim][dim];
{
/* Print the matrix here. */
...


The good news is, the code works and has its parameters in the order I'd like them to be.



The bad news is, I had to use the "old-style" function declaration syntax in order to reference the yet-to-be-declared argument dim in the declaration of M, which is apparently considered obsolete and dangerous.



Is there a straightforward way to do the same with the "new-style" function declarations WITHOUT changing the order of the parameters? (And if not, is it considered acceptable use of the old-style syntax in this particular situation?)










share|improve this question





















  • 1





    You can't; you specify the dimension before the matrix: void print_matrix(unsigned dim, int (*M)[dim][dim]). You're printing a 3D array, of course.

    – Jonathan Leffler
    Mar 28 at 0:00











  • Perhaps you can use a void pointer in the parameter list and assign it to the correct pointer type in the function.

    – Ctx
    Mar 28 at 0:05











  • I suspect that if you specified -Wpedantic-errors, you'd get compilation errors. Certainly, K&R compilers did not support VLA notation. There's a moderate chance you're using GCC and it is providing extensions that allow it to work.

    – Jonathan Leffler
    Mar 28 at 0:08











  • @JonathanLeffler Both Clang(6.0.0) and GCC(7.3.0) issued no complaints about my code, even with -std=c11 -pedantic-errors, but great point about the compatibility, of course. Even if the standard does not explicitly prohibit it (or so it seems), it's probably going to be poorly tested on the GCC/Clang side and non-idiomatic. I'm just surprised you can do that at all, to be honest.

    – undercat
    Mar 28 at 0:17












  • I'm surprised too. At one level, it makes sense. I don't spend much time worrying about what compilers can do with extensions over K&R with K&R function definitions. I aim to work in portable C, and accept that I have to put the size parameters before the arrays that use them in the prototype notation.

    – Jonathan Leffler
    Mar 28 at 0:25

















1















Compelled to use the variable length array feature for my auxiliary function that prints square matrices, I defined it as follows:



void print_matrix(M, dim)
unsigned dim;
int M[dim][dim];
{
/* Print the matrix here. */
...


The good news is, the code works and has its parameters in the order I'd like them to be.



The bad news is, I had to use the "old-style" function declaration syntax in order to reference the yet-to-be-declared argument dim in the declaration of M, which is apparently considered obsolete and dangerous.



Is there a straightforward way to do the same with the "new-style" function declarations WITHOUT changing the order of the parameters? (And if not, is it considered acceptable use of the old-style syntax in this particular situation?)










share|improve this question





















  • 1





    You can't; you specify the dimension before the matrix: void print_matrix(unsigned dim, int (*M)[dim][dim]). You're printing a 3D array, of course.

    – Jonathan Leffler
    Mar 28 at 0:00











  • Perhaps you can use a void pointer in the parameter list and assign it to the correct pointer type in the function.

    – Ctx
    Mar 28 at 0:05











  • I suspect that if you specified -Wpedantic-errors, you'd get compilation errors. Certainly, K&R compilers did not support VLA notation. There's a moderate chance you're using GCC and it is providing extensions that allow it to work.

    – Jonathan Leffler
    Mar 28 at 0:08











  • @JonathanLeffler Both Clang(6.0.0) and GCC(7.3.0) issued no complaints about my code, even with -std=c11 -pedantic-errors, but great point about the compatibility, of course. Even if the standard does not explicitly prohibit it (or so it seems), it's probably going to be poorly tested on the GCC/Clang side and non-idiomatic. I'm just surprised you can do that at all, to be honest.

    – undercat
    Mar 28 at 0:17












  • I'm surprised too. At one level, it makes sense. I don't spend much time worrying about what compilers can do with extensions over K&R with K&R function definitions. I aim to work in portable C, and accept that I have to put the size parameters before the arrays that use them in the prototype notation.

    – Jonathan Leffler
    Mar 28 at 0:25













1












1








1








Compelled to use the variable length array feature for my auxiliary function that prints square matrices, I defined it as follows:



void print_matrix(M, dim)
unsigned dim;
int M[dim][dim];
{
/* Print the matrix here. */
...


The good news is, the code works and has its parameters in the order I'd like them to be.



The bad news is, I had to use the "old-style" function declaration syntax in order to reference the yet-to-be-declared argument dim in the declaration of M, which is apparently considered obsolete and dangerous.



Is there a straightforward way to do the same with the "new-style" function declarations WITHOUT changing the order of the parameters? (And if not, is it considered acceptable use of the old-style syntax in this particular situation?)










share|improve this question
















Compelled to use the variable length array feature for my auxiliary function that prints square matrices, I defined it as follows:



void print_matrix(M, dim)
unsigned dim;
int M[dim][dim];
{
/* Print the matrix here. */
...


The good news is, the code works and has its parameters in the order I'd like them to be.



The bad news is, I had to use the "old-style" function declaration syntax in order to reference the yet-to-be-declared argument dim in the declaration of M, which is apparently considered obsolete and dangerous.



Is there a straightforward way to do the same with the "new-style" function declarations WITHOUT changing the order of the parameters? (And if not, is it considered acceptable use of the old-style syntax in this particular situation?)







c c99 variable-length-array






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 28 at 0:02







undercat

















asked Mar 27 at 23:55









undercatundercat

2371 silver badge14 bronze badges




2371 silver badge14 bronze badges










  • 1





    You can't; you specify the dimension before the matrix: void print_matrix(unsigned dim, int (*M)[dim][dim]). You're printing a 3D array, of course.

    – Jonathan Leffler
    Mar 28 at 0:00











  • Perhaps you can use a void pointer in the parameter list and assign it to the correct pointer type in the function.

    – Ctx
    Mar 28 at 0:05











  • I suspect that if you specified -Wpedantic-errors, you'd get compilation errors. Certainly, K&R compilers did not support VLA notation. There's a moderate chance you're using GCC and it is providing extensions that allow it to work.

    – Jonathan Leffler
    Mar 28 at 0:08











  • @JonathanLeffler Both Clang(6.0.0) and GCC(7.3.0) issued no complaints about my code, even with -std=c11 -pedantic-errors, but great point about the compatibility, of course. Even if the standard does not explicitly prohibit it (or so it seems), it's probably going to be poorly tested on the GCC/Clang side and non-idiomatic. I'm just surprised you can do that at all, to be honest.

    – undercat
    Mar 28 at 0:17












  • I'm surprised too. At one level, it makes sense. I don't spend much time worrying about what compilers can do with extensions over K&R with K&R function definitions. I aim to work in portable C, and accept that I have to put the size parameters before the arrays that use them in the prototype notation.

    – Jonathan Leffler
    Mar 28 at 0:25












  • 1





    You can't; you specify the dimension before the matrix: void print_matrix(unsigned dim, int (*M)[dim][dim]). You're printing a 3D array, of course.

    – Jonathan Leffler
    Mar 28 at 0:00











  • Perhaps you can use a void pointer in the parameter list and assign it to the correct pointer type in the function.

    – Ctx
    Mar 28 at 0:05











  • I suspect that if you specified -Wpedantic-errors, you'd get compilation errors. Certainly, K&R compilers did not support VLA notation. There's a moderate chance you're using GCC and it is providing extensions that allow it to work.

    – Jonathan Leffler
    Mar 28 at 0:08











  • @JonathanLeffler Both Clang(6.0.0) and GCC(7.3.0) issued no complaints about my code, even with -std=c11 -pedantic-errors, but great point about the compatibility, of course. Even if the standard does not explicitly prohibit it (or so it seems), it's probably going to be poorly tested on the GCC/Clang side and non-idiomatic. I'm just surprised you can do that at all, to be honest.

    – undercat
    Mar 28 at 0:17












  • I'm surprised too. At one level, it makes sense. I don't spend much time worrying about what compilers can do with extensions over K&R with K&R function definitions. I aim to work in portable C, and accept that I have to put the size parameters before the arrays that use them in the prototype notation.

    – Jonathan Leffler
    Mar 28 at 0:25







1




1





You can't; you specify the dimension before the matrix: void print_matrix(unsigned dim, int (*M)[dim][dim]). You're printing a 3D array, of course.

– Jonathan Leffler
Mar 28 at 0:00





You can't; you specify the dimension before the matrix: void print_matrix(unsigned dim, int (*M)[dim][dim]). You're printing a 3D array, of course.

– Jonathan Leffler
Mar 28 at 0:00













Perhaps you can use a void pointer in the parameter list and assign it to the correct pointer type in the function.

– Ctx
Mar 28 at 0:05





Perhaps you can use a void pointer in the parameter list and assign it to the correct pointer type in the function.

– Ctx
Mar 28 at 0:05













I suspect that if you specified -Wpedantic-errors, you'd get compilation errors. Certainly, K&R compilers did not support VLA notation. There's a moderate chance you're using GCC and it is providing extensions that allow it to work.

– Jonathan Leffler
Mar 28 at 0:08





I suspect that if you specified -Wpedantic-errors, you'd get compilation errors. Certainly, K&R compilers did not support VLA notation. There's a moderate chance you're using GCC and it is providing extensions that allow it to work.

– Jonathan Leffler
Mar 28 at 0:08













@JonathanLeffler Both Clang(6.0.0) and GCC(7.3.0) issued no complaints about my code, even with -std=c11 -pedantic-errors, but great point about the compatibility, of course. Even if the standard does not explicitly prohibit it (or so it seems), it's probably going to be poorly tested on the GCC/Clang side and non-idiomatic. I'm just surprised you can do that at all, to be honest.

– undercat
Mar 28 at 0:17






@JonathanLeffler Both Clang(6.0.0) and GCC(7.3.0) issued no complaints about my code, even with -std=c11 -pedantic-errors, but great point about the compatibility, of course. Even if the standard does not explicitly prohibit it (or so it seems), it's probably going to be poorly tested on the GCC/Clang side and non-idiomatic. I'm just surprised you can do that at all, to be honest.

– undercat
Mar 28 at 0:17














I'm surprised too. At one level, it makes sense. I don't spend much time worrying about what compilers can do with extensions over K&R with K&R function definitions. I aim to work in portable C, and accept that I have to put the size parameters before the arrays that use them in the prototype notation.

– Jonathan Leffler
Mar 28 at 0:25





I'm surprised too. At one level, it makes sense. I don't spend much time worrying about what compilers can do with extensions over K&R with K&R function definitions. I aim to work in portable C, and accept that I have to put the size parameters before the arrays that use them in the prototype notation.

– Jonathan Leffler
Mar 28 at 0:25












2 Answers
2






active

oldest

votes


















2















In portable (standard) C, you can't do what you show. You have to specify the dimension before the matrix. The original code in the question was:



void print_matrix(M, dim)
unsigned dim;
int (*M)[dim][dim];
{


and that can't be directly translated — it needs a prototype like this, with the dimension before the matrix:



void print_matrix(unsigned dim, int (*M)[dim][dim]);


This allows you to call the function with a 3D array. Or, with the revised notation in the question, you can print a 2D array:



void print_matrix(unsigned dim, int M[dim][dim]);



GCC provides an extension to assist. Quoting the manual:




If you want to pass the array first and the length afterward, you can use a forward declaration in the parameter list—another GNU extension.



struct entry
tester (int len; char data[len][len], int len)

/* … */



You can write any number of such parameter forward declarations in the parameter list. They can be separated by commas or semicolons, but the last one must end with a semicolon, which is followed by the “real” parameter declarations. Each forward declaration must match a “real” declaration in parameter name and data type. ISO C99 does not support parameter forward declarations.







share|improve this answer



























  • Using a combination of a prototype and an old-style declaration will avoid the need to throw long-standing argument-ordering conventions out the window.

    – supercat
    Apr 10 at 23:14











  • @supercat: what do you think the prototype looks like? The only ones that could work would be void print_matrix(int M[][*], unsigned dim) and void print_matrix(int M[*][*], unsigned dim). Interestingly, GCC seems to accept either notation, even with -pedantic; so does clang though with -Weverything it objects to the use of the VLA at all, simply on the grounds that it is a VLA ([-Werror,-Wvla]). […continued…]

    – Jonathan Leffler
    Apr 10 at 23:33












  • […continuation…] So, if you're prepared to write the function definition in the obsolescent style, using a feature added to the language after the style was declared obsolescent, then "yes, you can write the function definition K&R style and declare it with a prototype". I don't write functions K&R style any more, and I spend far too much time cleaning up a code base littered with them still (though the amount of litter has decreased dramatically recently — and bugs have been found). I won't ever advise anyone to write K&R style functions unless there is extreme duress applied to me.

    – Jonathan Leffler
    Apr 10 at 23:37











  • The prototypes using [*][*] are perfectly valid, and I'm not quite sure what objection you have to them. Things sometimes go from being obsolete to being necessary as a result of technological developments, and while there was never any reason other than standard-writer laziness for C99 to have made it necessary to use that syntax. In C89, the same caller-side semantics could be achieved with void test(double(*twodarr)[], int rows, int cols) ... which could then cast the argument to a double* and perform pointer arithmetic on it as appropriate.

    – supercat
    Apr 11 at 14:14











  • Being able to have a called function use a 2D array without the extra casting step would be nice, but I don't see that as any justification for requiring that functions using the new syntax be called differently. Since compilers have no need to know or care about the array sizes in the parameter list until the entire list had been parsed, all that would be necessary would be to have the compiler buffer up the size arguments and then evaluate them after parsing the declarations, and that's trivial compared with some of the other gymnastics forced upon compilers by clumsy corner cases in C99.

    – supercat
    Apr 11 at 14:19


















0















An old-style declaration which is preceded by a prototype is syntactically ugly, but is no more dangerous than a new style declaration.



void print_matrix(int M[*][*], unsigned dim);
void print_matrix(M, dim)
unsigned dim;
int M[dim][dim];

...



The authors of the Standard recognized that the old-style declarations were a valid, useful, and sufficient means of accomplishing the task, and decided that writing rules to allow with new-style declarations would be too much work, so they didn't want to bother. The combination of a prototype and old-style declaration is thus the only way to achieve the appropriate semantics.






share|improve this answer





























    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55388209%2freferencing-a-yet-to-be-mentioned-function-parameter-using-the-new-style-functio%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    2















    In portable (standard) C, you can't do what you show. You have to specify the dimension before the matrix. The original code in the question was:



    void print_matrix(M, dim)
    unsigned dim;
    int (*M)[dim][dim];
    {


    and that can't be directly translated — it needs a prototype like this, with the dimension before the matrix:



    void print_matrix(unsigned dim, int (*M)[dim][dim]);


    This allows you to call the function with a 3D array. Or, with the revised notation in the question, you can print a 2D array:



    void print_matrix(unsigned dim, int M[dim][dim]);



    GCC provides an extension to assist. Quoting the manual:




    If you want to pass the array first and the length afterward, you can use a forward declaration in the parameter list—another GNU extension.



    struct entry
    tester (int len; char data[len][len], int len)

    /* … */



    You can write any number of such parameter forward declarations in the parameter list. They can be separated by commas or semicolons, but the last one must end with a semicolon, which is followed by the “real” parameter declarations. Each forward declaration must match a “real” declaration in parameter name and data type. ISO C99 does not support parameter forward declarations.







    share|improve this answer



























    • Using a combination of a prototype and an old-style declaration will avoid the need to throw long-standing argument-ordering conventions out the window.

      – supercat
      Apr 10 at 23:14











    • @supercat: what do you think the prototype looks like? The only ones that could work would be void print_matrix(int M[][*], unsigned dim) and void print_matrix(int M[*][*], unsigned dim). Interestingly, GCC seems to accept either notation, even with -pedantic; so does clang though with -Weverything it objects to the use of the VLA at all, simply on the grounds that it is a VLA ([-Werror,-Wvla]). […continued…]

      – Jonathan Leffler
      Apr 10 at 23:33












    • […continuation…] So, if you're prepared to write the function definition in the obsolescent style, using a feature added to the language after the style was declared obsolescent, then "yes, you can write the function definition K&R style and declare it with a prototype". I don't write functions K&R style any more, and I spend far too much time cleaning up a code base littered with them still (though the amount of litter has decreased dramatically recently — and bugs have been found). I won't ever advise anyone to write K&R style functions unless there is extreme duress applied to me.

      – Jonathan Leffler
      Apr 10 at 23:37











    • The prototypes using [*][*] are perfectly valid, and I'm not quite sure what objection you have to them. Things sometimes go from being obsolete to being necessary as a result of technological developments, and while there was never any reason other than standard-writer laziness for C99 to have made it necessary to use that syntax. In C89, the same caller-side semantics could be achieved with void test(double(*twodarr)[], int rows, int cols) ... which could then cast the argument to a double* and perform pointer arithmetic on it as appropriate.

      – supercat
      Apr 11 at 14:14











    • Being able to have a called function use a 2D array without the extra casting step would be nice, but I don't see that as any justification for requiring that functions using the new syntax be called differently. Since compilers have no need to know or care about the array sizes in the parameter list until the entire list had been parsed, all that would be necessary would be to have the compiler buffer up the size arguments and then evaluate them after parsing the declarations, and that's trivial compared with some of the other gymnastics forced upon compilers by clumsy corner cases in C99.

      – supercat
      Apr 11 at 14:19















    2















    In portable (standard) C, you can't do what you show. You have to specify the dimension before the matrix. The original code in the question was:



    void print_matrix(M, dim)
    unsigned dim;
    int (*M)[dim][dim];
    {


    and that can't be directly translated — it needs a prototype like this, with the dimension before the matrix:



    void print_matrix(unsigned dim, int (*M)[dim][dim]);


    This allows you to call the function with a 3D array. Or, with the revised notation in the question, you can print a 2D array:



    void print_matrix(unsigned dim, int M[dim][dim]);



    GCC provides an extension to assist. Quoting the manual:




    If you want to pass the array first and the length afterward, you can use a forward declaration in the parameter list—another GNU extension.



    struct entry
    tester (int len; char data[len][len], int len)

    /* … */



    You can write any number of such parameter forward declarations in the parameter list. They can be separated by commas or semicolons, but the last one must end with a semicolon, which is followed by the “real” parameter declarations. Each forward declaration must match a “real” declaration in parameter name and data type. ISO C99 does not support parameter forward declarations.







    share|improve this answer



























    • Using a combination of a prototype and an old-style declaration will avoid the need to throw long-standing argument-ordering conventions out the window.

      – supercat
      Apr 10 at 23:14











    • @supercat: what do you think the prototype looks like? The only ones that could work would be void print_matrix(int M[][*], unsigned dim) and void print_matrix(int M[*][*], unsigned dim). Interestingly, GCC seems to accept either notation, even with -pedantic; so does clang though with -Weverything it objects to the use of the VLA at all, simply on the grounds that it is a VLA ([-Werror,-Wvla]). […continued…]

      – Jonathan Leffler
      Apr 10 at 23:33












    • […continuation…] So, if you're prepared to write the function definition in the obsolescent style, using a feature added to the language after the style was declared obsolescent, then "yes, you can write the function definition K&R style and declare it with a prototype". I don't write functions K&R style any more, and I spend far too much time cleaning up a code base littered with them still (though the amount of litter has decreased dramatically recently — and bugs have been found). I won't ever advise anyone to write K&R style functions unless there is extreme duress applied to me.

      – Jonathan Leffler
      Apr 10 at 23:37











    • The prototypes using [*][*] are perfectly valid, and I'm not quite sure what objection you have to them. Things sometimes go from being obsolete to being necessary as a result of technological developments, and while there was never any reason other than standard-writer laziness for C99 to have made it necessary to use that syntax. In C89, the same caller-side semantics could be achieved with void test(double(*twodarr)[], int rows, int cols) ... which could then cast the argument to a double* and perform pointer arithmetic on it as appropriate.

      – supercat
      Apr 11 at 14:14











    • Being able to have a called function use a 2D array without the extra casting step would be nice, but I don't see that as any justification for requiring that functions using the new syntax be called differently. Since compilers have no need to know or care about the array sizes in the parameter list until the entire list had been parsed, all that would be necessary would be to have the compiler buffer up the size arguments and then evaluate them after parsing the declarations, and that's trivial compared with some of the other gymnastics forced upon compilers by clumsy corner cases in C99.

      – supercat
      Apr 11 at 14:19













    2














    2










    2









    In portable (standard) C, you can't do what you show. You have to specify the dimension before the matrix. The original code in the question was:



    void print_matrix(M, dim)
    unsigned dim;
    int (*M)[dim][dim];
    {


    and that can't be directly translated — it needs a prototype like this, with the dimension before the matrix:



    void print_matrix(unsigned dim, int (*M)[dim][dim]);


    This allows you to call the function with a 3D array. Or, with the revised notation in the question, you can print a 2D array:



    void print_matrix(unsigned dim, int M[dim][dim]);



    GCC provides an extension to assist. Quoting the manual:




    If you want to pass the array first and the length afterward, you can use a forward declaration in the parameter list—another GNU extension.



    struct entry
    tester (int len; char data[len][len], int len)

    /* … */



    You can write any number of such parameter forward declarations in the parameter list. They can be separated by commas or semicolons, but the last one must end with a semicolon, which is followed by the “real” parameter declarations. Each forward declaration must match a “real” declaration in parameter name and data type. ISO C99 does not support parameter forward declarations.







    share|improve this answer















    In portable (standard) C, you can't do what you show. You have to specify the dimension before the matrix. The original code in the question was:



    void print_matrix(M, dim)
    unsigned dim;
    int (*M)[dim][dim];
    {


    and that can't be directly translated — it needs a prototype like this, with the dimension before the matrix:



    void print_matrix(unsigned dim, int (*M)[dim][dim]);


    This allows you to call the function with a 3D array. Or, with the revised notation in the question, you can print a 2D array:



    void print_matrix(unsigned dim, int M[dim][dim]);



    GCC provides an extension to assist. Quoting the manual:




    If you want to pass the array first and the length afterward, you can use a forward declaration in the parameter list—another GNU extension.



    struct entry
    tester (int len; char data[len][len], int len)

    /* … */



    You can write any number of such parameter forward declarations in the parameter list. They can be separated by commas or semicolons, but the last one must end with a semicolon, which is followed by the “real” parameter declarations. Each forward declaration must match a “real” declaration in parameter name and data type. ISO C99 does not support parameter forward declarations.








    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Mar 28 at 0:14

























    answered Mar 28 at 0:06









    Jonathan LefflerJonathan Leffler

    592k97 gold badges710 silver badges1066 bronze badges




    592k97 gold badges710 silver badges1066 bronze badges















    • Using a combination of a prototype and an old-style declaration will avoid the need to throw long-standing argument-ordering conventions out the window.

      – supercat
      Apr 10 at 23:14











    • @supercat: what do you think the prototype looks like? The only ones that could work would be void print_matrix(int M[][*], unsigned dim) and void print_matrix(int M[*][*], unsigned dim). Interestingly, GCC seems to accept either notation, even with -pedantic; so does clang though with -Weverything it objects to the use of the VLA at all, simply on the grounds that it is a VLA ([-Werror,-Wvla]). […continued…]

      – Jonathan Leffler
      Apr 10 at 23:33












    • […continuation…] So, if you're prepared to write the function definition in the obsolescent style, using a feature added to the language after the style was declared obsolescent, then "yes, you can write the function definition K&R style and declare it with a prototype". I don't write functions K&R style any more, and I spend far too much time cleaning up a code base littered with them still (though the amount of litter has decreased dramatically recently — and bugs have been found). I won't ever advise anyone to write K&R style functions unless there is extreme duress applied to me.

      – Jonathan Leffler
      Apr 10 at 23:37











    • The prototypes using [*][*] are perfectly valid, and I'm not quite sure what objection you have to them. Things sometimes go from being obsolete to being necessary as a result of technological developments, and while there was never any reason other than standard-writer laziness for C99 to have made it necessary to use that syntax. In C89, the same caller-side semantics could be achieved with void test(double(*twodarr)[], int rows, int cols) ... which could then cast the argument to a double* and perform pointer arithmetic on it as appropriate.

      – supercat
      Apr 11 at 14:14











    • Being able to have a called function use a 2D array without the extra casting step would be nice, but I don't see that as any justification for requiring that functions using the new syntax be called differently. Since compilers have no need to know or care about the array sizes in the parameter list until the entire list had been parsed, all that would be necessary would be to have the compiler buffer up the size arguments and then evaluate them after parsing the declarations, and that's trivial compared with some of the other gymnastics forced upon compilers by clumsy corner cases in C99.

      – supercat
      Apr 11 at 14:19

















    • Using a combination of a prototype and an old-style declaration will avoid the need to throw long-standing argument-ordering conventions out the window.

      – supercat
      Apr 10 at 23:14











    • @supercat: what do you think the prototype looks like? The only ones that could work would be void print_matrix(int M[][*], unsigned dim) and void print_matrix(int M[*][*], unsigned dim). Interestingly, GCC seems to accept either notation, even with -pedantic; so does clang though with -Weverything it objects to the use of the VLA at all, simply on the grounds that it is a VLA ([-Werror,-Wvla]). […continued…]

      – Jonathan Leffler
      Apr 10 at 23:33












    • […continuation…] So, if you're prepared to write the function definition in the obsolescent style, using a feature added to the language after the style was declared obsolescent, then "yes, you can write the function definition K&R style and declare it with a prototype". I don't write functions K&R style any more, and I spend far too much time cleaning up a code base littered with them still (though the amount of litter has decreased dramatically recently — and bugs have been found). I won't ever advise anyone to write K&R style functions unless there is extreme duress applied to me.

      – Jonathan Leffler
      Apr 10 at 23:37











    • The prototypes using [*][*] are perfectly valid, and I'm not quite sure what objection you have to them. Things sometimes go from being obsolete to being necessary as a result of technological developments, and while there was never any reason other than standard-writer laziness for C99 to have made it necessary to use that syntax. In C89, the same caller-side semantics could be achieved with void test(double(*twodarr)[], int rows, int cols) ... which could then cast the argument to a double* and perform pointer arithmetic on it as appropriate.

      – supercat
      Apr 11 at 14:14











    • Being able to have a called function use a 2D array without the extra casting step would be nice, but I don't see that as any justification for requiring that functions using the new syntax be called differently. Since compilers have no need to know or care about the array sizes in the parameter list until the entire list had been parsed, all that would be necessary would be to have the compiler buffer up the size arguments and then evaluate them after parsing the declarations, and that's trivial compared with some of the other gymnastics forced upon compilers by clumsy corner cases in C99.

      – supercat
      Apr 11 at 14:19
















    Using a combination of a prototype and an old-style declaration will avoid the need to throw long-standing argument-ordering conventions out the window.

    – supercat
    Apr 10 at 23:14





    Using a combination of a prototype and an old-style declaration will avoid the need to throw long-standing argument-ordering conventions out the window.

    – supercat
    Apr 10 at 23:14













    @supercat: what do you think the prototype looks like? The only ones that could work would be void print_matrix(int M[][*], unsigned dim) and void print_matrix(int M[*][*], unsigned dim). Interestingly, GCC seems to accept either notation, even with -pedantic; so does clang though with -Weverything it objects to the use of the VLA at all, simply on the grounds that it is a VLA ([-Werror,-Wvla]). […continued…]

    – Jonathan Leffler
    Apr 10 at 23:33






    @supercat: what do you think the prototype looks like? The only ones that could work would be void print_matrix(int M[][*], unsigned dim) and void print_matrix(int M[*][*], unsigned dim). Interestingly, GCC seems to accept either notation, even with -pedantic; so does clang though with -Weverything it objects to the use of the VLA at all, simply on the grounds that it is a VLA ([-Werror,-Wvla]). […continued…]

    – Jonathan Leffler
    Apr 10 at 23:33














    […continuation…] So, if you're prepared to write the function definition in the obsolescent style, using a feature added to the language after the style was declared obsolescent, then "yes, you can write the function definition K&R style and declare it with a prototype". I don't write functions K&R style any more, and I spend far too much time cleaning up a code base littered with them still (though the amount of litter has decreased dramatically recently — and bugs have been found). I won't ever advise anyone to write K&R style functions unless there is extreme duress applied to me.

    – Jonathan Leffler
    Apr 10 at 23:37





    […continuation…] So, if you're prepared to write the function definition in the obsolescent style, using a feature added to the language after the style was declared obsolescent, then "yes, you can write the function definition K&R style and declare it with a prototype". I don't write functions K&R style any more, and I spend far too much time cleaning up a code base littered with them still (though the amount of litter has decreased dramatically recently — and bugs have been found). I won't ever advise anyone to write K&R style functions unless there is extreme duress applied to me.

    – Jonathan Leffler
    Apr 10 at 23:37













    The prototypes using [*][*] are perfectly valid, and I'm not quite sure what objection you have to them. Things sometimes go from being obsolete to being necessary as a result of technological developments, and while there was never any reason other than standard-writer laziness for C99 to have made it necessary to use that syntax. In C89, the same caller-side semantics could be achieved with void test(double(*twodarr)[], int rows, int cols) ... which could then cast the argument to a double* and perform pointer arithmetic on it as appropriate.

    – supercat
    Apr 11 at 14:14





    The prototypes using [*][*] are perfectly valid, and I'm not quite sure what objection you have to them. Things sometimes go from being obsolete to being necessary as a result of technological developments, and while there was never any reason other than standard-writer laziness for C99 to have made it necessary to use that syntax. In C89, the same caller-side semantics could be achieved with void test(double(*twodarr)[], int rows, int cols) ... which could then cast the argument to a double* and perform pointer arithmetic on it as appropriate.

    – supercat
    Apr 11 at 14:14













    Being able to have a called function use a 2D array without the extra casting step would be nice, but I don't see that as any justification for requiring that functions using the new syntax be called differently. Since compilers have no need to know or care about the array sizes in the parameter list until the entire list had been parsed, all that would be necessary would be to have the compiler buffer up the size arguments and then evaluate them after parsing the declarations, and that's trivial compared with some of the other gymnastics forced upon compilers by clumsy corner cases in C99.

    – supercat
    Apr 11 at 14:19





    Being able to have a called function use a 2D array without the extra casting step would be nice, but I don't see that as any justification for requiring that functions using the new syntax be called differently. Since compilers have no need to know or care about the array sizes in the parameter list until the entire list had been parsed, all that would be necessary would be to have the compiler buffer up the size arguments and then evaluate them after parsing the declarations, and that's trivial compared with some of the other gymnastics forced upon compilers by clumsy corner cases in C99.

    – supercat
    Apr 11 at 14:19













    0















    An old-style declaration which is preceded by a prototype is syntactically ugly, but is no more dangerous than a new style declaration.



    void print_matrix(int M[*][*], unsigned dim);
    void print_matrix(M, dim)
    unsigned dim;
    int M[dim][dim];

    ...



    The authors of the Standard recognized that the old-style declarations were a valid, useful, and sufficient means of accomplishing the task, and decided that writing rules to allow with new-style declarations would be too much work, so they didn't want to bother. The combination of a prototype and old-style declaration is thus the only way to achieve the appropriate semantics.






    share|improve this answer































      0















      An old-style declaration which is preceded by a prototype is syntactically ugly, but is no more dangerous than a new style declaration.



      void print_matrix(int M[*][*], unsigned dim);
      void print_matrix(M, dim)
      unsigned dim;
      int M[dim][dim];

      ...



      The authors of the Standard recognized that the old-style declarations were a valid, useful, and sufficient means of accomplishing the task, and decided that writing rules to allow with new-style declarations would be too much work, so they didn't want to bother. The combination of a prototype and old-style declaration is thus the only way to achieve the appropriate semantics.






      share|improve this answer





























        0














        0










        0









        An old-style declaration which is preceded by a prototype is syntactically ugly, but is no more dangerous than a new style declaration.



        void print_matrix(int M[*][*], unsigned dim);
        void print_matrix(M, dim)
        unsigned dim;
        int M[dim][dim];

        ...



        The authors of the Standard recognized that the old-style declarations were a valid, useful, and sufficient means of accomplishing the task, and decided that writing rules to allow with new-style declarations would be too much work, so they didn't want to bother. The combination of a prototype and old-style declaration is thus the only way to achieve the appropriate semantics.






        share|improve this answer















        An old-style declaration which is preceded by a prototype is syntactically ugly, but is no more dangerous than a new style declaration.



        void print_matrix(int M[*][*], unsigned dim);
        void print_matrix(M, dim)
        unsigned dim;
        int M[dim][dim];

        ...



        The authors of the Standard recognized that the old-style declarations were a valid, useful, and sufficient means of accomplishing the task, and decided that writing rules to allow with new-style declarations would be too much work, so they didn't want to bother. The combination of a prototype and old-style declaration is thus the only way to achieve the appropriate semantics.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Apr 11 at 14:19

























        answered Apr 10 at 23:12









        supercatsupercat

        60.1k4 gold badges127 silver badges162 bronze badges




        60.1k4 gold badges127 silver badges162 bronze badges






























            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55388209%2freferencing-a-yet-to-be-mentioned-function-parameter-using-the-new-style-functio%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Kamusi Yaliyomo Aina za kamusi | Muundo wa kamusi | Faida za kamusi | Dhima ya picha katika kamusi | Marejeo | Tazama pia | Viungo vya nje | UrambazajiKuhusu kamusiGo-SwahiliWiki-KamusiKamusi ya Kiswahili na Kiingerezakuihariri na kuongeza habari

            Swift 4 - func physicsWorld not invoked on collision? The Next CEO of Stack OverflowHow to call Objective-C code from Swift#ifdef replacement in the Swift language@selector() in Swift?#pragma mark in Swift?Swift for loop: for index, element in array?dispatch_after - GCD in Swift?Swift Beta performance: sorting arraysSplit a String into an array in Swift?The use of Swift 3 @objc inference in Swift 4 mode is deprecated?How to optimize UITableViewCell, because my UITableView lags

            Access current req object everywhere in Node.js ExpressWhy are global variables considered bad practice? (node.js)Using req & res across functionsHow do I get the path to the current script with Node.js?What is Node.js' Connect, Express and “middleware”?Node.js w/ express error handling in callbackHow to access the GET parameters after “?” in Express?Modify Node.js req object parametersAccess “app” variable inside of ExpressJS/ConnectJS middleware?Node.js Express app - request objectAngular Http Module considered middleware?Session variables in ExpressJSAdd properties to the req object in expressjs with Typescript