Defining a return variable in the function declaration. Is this legitimate in modern C++?












8















I am a big fan of CodeSignal, but I found a strange piece of C++ grammar (the first line):



string r, longestDigitsPrefix(string s)
{
for(auto const c : s)
{
if(isdigit(c))
r += c;
else
break;
}
return r;
}


Is defining string r, in the function declaration valid in modern C++?



The above code compiles and passes all tests in the CodeSignal console, but it produced a compiler error when I tried to compile locally (--std=c++14).



If this is valid grammar in modern C++ and which standard revision does it comply with?










share|improve this question




















  • 1





    Where did you find this and what compiler accept this? Never saw this (invalid) grammar.

    – Matthieu Brucher
    2 hours ago











  • @MatthieuBrucher - Upon closer inspection, different branches of the grammar production.

    – StoryTeller
    2 hours ago











  • @StoryTeller Meaning that it's valid or invalid?

    – Matthieu Brucher
    2 hours ago








  • 1





    @MatthieuBrucher - Invalid. The grammar production I was looking it described decl a; decl b; - a or b can be function definitions (note the semicolon). But a function definition may not appear in decl a, b;

    – StoryTeller
    2 hours ago













  • string r, longestDigitsPrefix(string s); would be valid. The code you posted is invalid.

    – Kamil Cuk
    2 hours ago


















8















I am a big fan of CodeSignal, but I found a strange piece of C++ grammar (the first line):



string r, longestDigitsPrefix(string s)
{
for(auto const c : s)
{
if(isdigit(c))
r += c;
else
break;
}
return r;
}


Is defining string r, in the function declaration valid in modern C++?



The above code compiles and passes all tests in the CodeSignal console, but it produced a compiler error when I tried to compile locally (--std=c++14).



If this is valid grammar in modern C++ and which standard revision does it comply with?










share|improve this question




















  • 1





    Where did you find this and what compiler accept this? Never saw this (invalid) grammar.

    – Matthieu Brucher
    2 hours ago











  • @MatthieuBrucher - Upon closer inspection, different branches of the grammar production.

    – StoryTeller
    2 hours ago











  • @StoryTeller Meaning that it's valid or invalid?

    – Matthieu Brucher
    2 hours ago








  • 1





    @MatthieuBrucher - Invalid. The grammar production I was looking it described decl a; decl b; - a or b can be function definitions (note the semicolon). But a function definition may not appear in decl a, b;

    – StoryTeller
    2 hours ago













  • string r, longestDigitsPrefix(string s); would be valid. The code you posted is invalid.

    – Kamil Cuk
    2 hours ago
















8












8








8


2






I am a big fan of CodeSignal, but I found a strange piece of C++ grammar (the first line):



string r, longestDigitsPrefix(string s)
{
for(auto const c : s)
{
if(isdigit(c))
r += c;
else
break;
}
return r;
}


Is defining string r, in the function declaration valid in modern C++?



The above code compiles and passes all tests in the CodeSignal console, but it produced a compiler error when I tried to compile locally (--std=c++14).



If this is valid grammar in modern C++ and which standard revision does it comply with?










share|improve this question
















I am a big fan of CodeSignal, but I found a strange piece of C++ grammar (the first line):



string r, longestDigitsPrefix(string s)
{
for(auto const c : s)
{
if(isdigit(c))
r += c;
else
break;
}
return r;
}


Is defining string r, in the function declaration valid in modern C++?



The above code compiles and passes all tests in the CodeSignal console, but it produced a compiler error when I tried to compile locally (--std=c++14).



If this is valid grammar in modern C++ and which standard revision does it comply with?







c++ language-lawyer declaration






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 1 hour ago









Peter Mortensen

13.5k1984111




13.5k1984111










asked 3 hours ago









HarryHarry

969




969








  • 1





    Where did you find this and what compiler accept this? Never saw this (invalid) grammar.

    – Matthieu Brucher
    2 hours ago











  • @MatthieuBrucher - Upon closer inspection, different branches of the grammar production.

    – StoryTeller
    2 hours ago











  • @StoryTeller Meaning that it's valid or invalid?

    – Matthieu Brucher
    2 hours ago








  • 1





    @MatthieuBrucher - Invalid. The grammar production I was looking it described decl a; decl b; - a or b can be function definitions (note the semicolon). But a function definition may not appear in decl a, b;

    – StoryTeller
    2 hours ago













  • string r, longestDigitsPrefix(string s); would be valid. The code you posted is invalid.

    – Kamil Cuk
    2 hours ago
















  • 1





    Where did you find this and what compiler accept this? Never saw this (invalid) grammar.

    – Matthieu Brucher
    2 hours ago











  • @MatthieuBrucher - Upon closer inspection, different branches of the grammar production.

    – StoryTeller
    2 hours ago











  • @StoryTeller Meaning that it's valid or invalid?

    – Matthieu Brucher
    2 hours ago








  • 1





    @MatthieuBrucher - Invalid. The grammar production I was looking it described decl a; decl b; - a or b can be function definitions (note the semicolon). But a function definition may not appear in decl a, b;

    – StoryTeller
    2 hours ago













  • string r, longestDigitsPrefix(string s); would be valid. The code you posted is invalid.

    – Kamil Cuk
    2 hours ago










1




1





Where did you find this and what compiler accept this? Never saw this (invalid) grammar.

– Matthieu Brucher
2 hours ago





Where did you find this and what compiler accept this? Never saw this (invalid) grammar.

– Matthieu Brucher
2 hours ago













@MatthieuBrucher - Upon closer inspection, different branches of the grammar production.

– StoryTeller
2 hours ago





@MatthieuBrucher - Upon closer inspection, different branches of the grammar production.

– StoryTeller
2 hours ago













@StoryTeller Meaning that it's valid or invalid?

– Matthieu Brucher
2 hours ago







@StoryTeller Meaning that it's valid or invalid?

– Matthieu Brucher
2 hours ago






1




1





@MatthieuBrucher - Invalid. The grammar production I was looking it described decl a; decl b; - a or b can be function definitions (note the semicolon). But a function definition may not appear in decl a, b;

– StoryTeller
2 hours ago







@MatthieuBrucher - Invalid. The grammar production I was looking it described decl a; decl b; - a or b can be function definitions (note the semicolon). But a function definition may not appear in decl a, b;

– StoryTeller
2 hours ago















string r, longestDigitsPrefix(string s); would be valid. The code you posted is invalid.

– Kamil Cuk
2 hours ago







string r, longestDigitsPrefix(string s); would be valid. The code you posted is invalid.

– Kamil Cuk
2 hours ago














5 Answers
5






active

oldest

votes


















8














Yeah, C++ grammar is weird. Basically, when it comes to declarations (and only declarations), we have this thing where:



T D1, D2, ... ,Dn;


means ([dcl.dcl]/3):



T D1;
T D2;
...
T Dn;


This will be familiar in the normal cases:



int a, b; // declares two ints


And probably in the cases you've been told to worry about:



int* a, b, *c; // a and c are pointers to int, b is just an int


But declarators can introduce other things too:



int *a, b[10], (*c)[10], d(int);


Here a is a pointer to int, b is an array of 10 ints, c is a pointer to an array of 10 ints, and d is a function taking an int returning an int.





However, this only applies to declarations. So this:



string r, longestDigitsPrefix(string s);


is a valid C++ declaration that declares r to be a string and longestDigitsPrefix to be a function taking a string and returning a string.



But this:



string r, longestDigitsPrefix(string s) { return s; }


is invalid C++. Function definitions have their own grammar and cannot appear as part of the init-declarator-list.



The definition of that function is also bad, since it's using a global variable to keep track of state. So even if it were valid, longestDigitsPrefix("12c") would return "12" the first time but "1212" the second time...






share|improve this answer
























  • I think your answer is not complete, one could also think about the "Built-in comma operator The comma operator expressions have the form E1 , E2 In a comma expression E1, E2, the expression E1 is evaluated, its result is discarded " en.cppreference.com/w/cpp/language/operator_other

    – Superlokkus
    1 hour ago






  • 3





    The comma operator can be used as part of an expression, but the code proposed here syntactically isn’t an expression (it’s a statement), so I don’t think there’s a need to look at the comma operator in refuting that this is syntactically correct.

    – templatetypedef
    1 hour ago











  • @templatetypedef It's hard to reason about grammatically incorrect statements, I was trying to cover all cases one could think of when seeing a comma in such context, but I see your point.

    – Superlokkus
    20 mins ago



















2














By reading the ISO C++14 draft N4140 Annex A [gram], I'm pretty sure it's incorrect since I cant find a way to deduce the grammar from a translation unit from




translation-unit -> declaration-seq -> declaration -> block-declaration | function-definition | linkage-specification | ...



function-definition: attribute-specifier-seqopt decl-specifier-seqopt
declarator virt-specifier-seqopt function-body



declarator: ptr-declarator noptr-declarator parameters-and-qualifiers
trailing-return-type




But your line is more the comma operator but its grammar is:




expression:
assignment-expression | expression , assignment-expression



assignment-expression: conditional-expression | logical-or-expression |
assignment-operator | initializer-clause | throw-expression




And there is no way from assignment-expression to function-definition



Update:
Thanks to Barry, another way to try to buttom-up parse your text is by rather try to get from a init-declarator-list (which you can get from block-declaration) to a function-definition:




init-declarator-list: init-declarator | init-declarator-list ,
init-declarator



init-declarator: declarator initializeropt




And




declarator: ptr-declarator noptr-declarator parameters-and-qualifiers
trailing-return-type




Would allow you a function declaration but not definition. So this odd code would be legal:



#include <string>
using std::string;

string r, longestDigitsPrefix(string s);

string longestDigitsPrefix(string s) {
for(auto const c : s)
{
if(isdigit(c))
r += c;
else
break;
}
return r;
}

int main(int argc, char *argv) {
longestDigitsPrefix("foo");

return 0;
}


However I could be wrong, since I'm not used to use the formal grammar of C++, which is normal since it's grammar is very complex, and has some non trivial behaviour.






share|improve this answer

































    -1














    To my knowledge, this is not a valid function declaration.



    The prefix in functions can be used only as a way to define what type is the function's "returning" variable, not the variable itself.



    You can however declare a variable outside your function (thus making it global) and modify it inside the function, as you may have probably attempted, but then you need to pass said variable as a reference in your function's arguments. You would also need to set your function as void, since it is not going to return the variable, but just modify it



    Example



    std::string foo = "Hello";

    void foo_func(std::string &string)
    { //do something with the string
    }

    //call the function and modify the global "foo" string
    foo_func(foo);





    share|improve this answer
























    • As the question has a language-lawyer tag, we expect answers with C++ standard quotes.

      – Matthieu Brucher
      22 mins ago





















    -1














    Why wouldn't it be possible? After all, it's just two declarations with strings, and they can be grouped. There are examples like this in the cppreference page for declarations; they just lack function bodies.



    My g++ (GCC) 8.2.1 allows this within a class. This will compile without warning (-Wall) and return 42.



    struct Weird {
    int r, getR() {return r;};
    };

    int main() {
    Weird w={42};
    return w.getR();
    }





    share|improve this answer





















    • 1





      That's the point, they lack function bodies. Here there is a body, and that's the main difference. Also the case that works is different from OP.

      – Matthieu Brucher
      1 hour ago











    • GCC won't accept this when outside a class. Even inside a class this is invalid code, and it isn't allowed by clang.

      – interjay
      59 mins ago



















    -3














    This code combines a variable declaration with a function declaration. The function uses the (global) variable and returns its value eventually. No, I don't think this kind of code is usual C++ although it is formally valid.






    share|improve this answer



















    • 1





      Can you show a compiler that accept this? If it's a global variable, then it misses the return type?

      – Matthieu Brucher
      2 hours ago











    • The return type is 'string'.

      – another-dave
      2 hours ago











    • string r, s; should not be surprising. Neither should be string r, *s;, although it's IMHO bad style. So, why is string r, function() {return r;}; surprising?

      – Ulrich Eckhardt
      2 hours ago






    • 3





      Yes, the return type is string, but only valid if there is a prototype. The function definition like OP's code doesn't work.

      – Matthieu Brucher
      2 hours ago











    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%2f54277381%2fdefining-a-return-variable-in-the-function-declaration-is-this-legitimate-in-mo%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    5 Answers
    5






    active

    oldest

    votes








    5 Answers
    5






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    8














    Yeah, C++ grammar is weird. Basically, when it comes to declarations (and only declarations), we have this thing where:



    T D1, D2, ... ,Dn;


    means ([dcl.dcl]/3):



    T D1;
    T D2;
    ...
    T Dn;


    This will be familiar in the normal cases:



    int a, b; // declares two ints


    And probably in the cases you've been told to worry about:



    int* a, b, *c; // a and c are pointers to int, b is just an int


    But declarators can introduce other things too:



    int *a, b[10], (*c)[10], d(int);


    Here a is a pointer to int, b is an array of 10 ints, c is a pointer to an array of 10 ints, and d is a function taking an int returning an int.





    However, this only applies to declarations. So this:



    string r, longestDigitsPrefix(string s);


    is a valid C++ declaration that declares r to be a string and longestDigitsPrefix to be a function taking a string and returning a string.



    But this:



    string r, longestDigitsPrefix(string s) { return s; }


    is invalid C++. Function definitions have their own grammar and cannot appear as part of the init-declarator-list.



    The definition of that function is also bad, since it's using a global variable to keep track of state. So even if it were valid, longestDigitsPrefix("12c") would return "12" the first time but "1212" the second time...






    share|improve this answer
























    • I think your answer is not complete, one could also think about the "Built-in comma operator The comma operator expressions have the form E1 , E2 In a comma expression E1, E2, the expression E1 is evaluated, its result is discarded " en.cppreference.com/w/cpp/language/operator_other

      – Superlokkus
      1 hour ago






    • 3





      The comma operator can be used as part of an expression, but the code proposed here syntactically isn’t an expression (it’s a statement), so I don’t think there’s a need to look at the comma operator in refuting that this is syntactically correct.

      – templatetypedef
      1 hour ago











    • @templatetypedef It's hard to reason about grammatically incorrect statements, I was trying to cover all cases one could think of when seeing a comma in such context, but I see your point.

      – Superlokkus
      20 mins ago
















    8














    Yeah, C++ grammar is weird. Basically, when it comes to declarations (and only declarations), we have this thing where:



    T D1, D2, ... ,Dn;


    means ([dcl.dcl]/3):



    T D1;
    T D2;
    ...
    T Dn;


    This will be familiar in the normal cases:



    int a, b; // declares two ints


    And probably in the cases you've been told to worry about:



    int* a, b, *c; // a and c are pointers to int, b is just an int


    But declarators can introduce other things too:



    int *a, b[10], (*c)[10], d(int);


    Here a is a pointer to int, b is an array of 10 ints, c is a pointer to an array of 10 ints, and d is a function taking an int returning an int.





    However, this only applies to declarations. So this:



    string r, longestDigitsPrefix(string s);


    is a valid C++ declaration that declares r to be a string and longestDigitsPrefix to be a function taking a string and returning a string.



    But this:



    string r, longestDigitsPrefix(string s) { return s; }


    is invalid C++. Function definitions have their own grammar and cannot appear as part of the init-declarator-list.



    The definition of that function is also bad, since it's using a global variable to keep track of state. So even if it were valid, longestDigitsPrefix("12c") would return "12" the first time but "1212" the second time...






    share|improve this answer
























    • I think your answer is not complete, one could also think about the "Built-in comma operator The comma operator expressions have the form E1 , E2 In a comma expression E1, E2, the expression E1 is evaluated, its result is discarded " en.cppreference.com/w/cpp/language/operator_other

      – Superlokkus
      1 hour ago






    • 3





      The comma operator can be used as part of an expression, but the code proposed here syntactically isn’t an expression (it’s a statement), so I don’t think there’s a need to look at the comma operator in refuting that this is syntactically correct.

      – templatetypedef
      1 hour ago











    • @templatetypedef It's hard to reason about grammatically incorrect statements, I was trying to cover all cases one could think of when seeing a comma in such context, but I see your point.

      – Superlokkus
      20 mins ago














    8












    8








    8







    Yeah, C++ grammar is weird. Basically, when it comes to declarations (and only declarations), we have this thing where:



    T D1, D2, ... ,Dn;


    means ([dcl.dcl]/3):



    T D1;
    T D2;
    ...
    T Dn;


    This will be familiar in the normal cases:



    int a, b; // declares two ints


    And probably in the cases you've been told to worry about:



    int* a, b, *c; // a and c are pointers to int, b is just an int


    But declarators can introduce other things too:



    int *a, b[10], (*c)[10], d(int);


    Here a is a pointer to int, b is an array of 10 ints, c is a pointer to an array of 10 ints, and d is a function taking an int returning an int.





    However, this only applies to declarations. So this:



    string r, longestDigitsPrefix(string s);


    is a valid C++ declaration that declares r to be a string and longestDigitsPrefix to be a function taking a string and returning a string.



    But this:



    string r, longestDigitsPrefix(string s) { return s; }


    is invalid C++. Function definitions have their own grammar and cannot appear as part of the init-declarator-list.



    The definition of that function is also bad, since it's using a global variable to keep track of state. So even if it were valid, longestDigitsPrefix("12c") would return "12" the first time but "1212" the second time...






    share|improve this answer













    Yeah, C++ grammar is weird. Basically, when it comes to declarations (and only declarations), we have this thing where:



    T D1, D2, ... ,Dn;


    means ([dcl.dcl]/3):



    T D1;
    T D2;
    ...
    T Dn;


    This will be familiar in the normal cases:



    int a, b; // declares two ints


    And probably in the cases you've been told to worry about:



    int* a, b, *c; // a and c are pointers to int, b is just an int


    But declarators can introduce other things too:



    int *a, b[10], (*c)[10], d(int);


    Here a is a pointer to int, b is an array of 10 ints, c is a pointer to an array of 10 ints, and d is a function taking an int returning an int.





    However, this only applies to declarations. So this:



    string r, longestDigitsPrefix(string s);


    is a valid C++ declaration that declares r to be a string and longestDigitsPrefix to be a function taking a string and returning a string.



    But this:



    string r, longestDigitsPrefix(string s) { return s; }


    is invalid C++. Function definitions have their own grammar and cannot appear as part of the init-declarator-list.



    The definition of that function is also bad, since it's using a global variable to keep track of state. So even if it were valid, longestDigitsPrefix("12c") would return "12" the first time but "1212" the second time...







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered 1 hour ago









    BarryBarry

    179k19310570




    179k19310570













    • I think your answer is not complete, one could also think about the "Built-in comma operator The comma operator expressions have the form E1 , E2 In a comma expression E1, E2, the expression E1 is evaluated, its result is discarded " en.cppreference.com/w/cpp/language/operator_other

      – Superlokkus
      1 hour ago






    • 3





      The comma operator can be used as part of an expression, but the code proposed here syntactically isn’t an expression (it’s a statement), so I don’t think there’s a need to look at the comma operator in refuting that this is syntactically correct.

      – templatetypedef
      1 hour ago











    • @templatetypedef It's hard to reason about grammatically incorrect statements, I was trying to cover all cases one could think of when seeing a comma in such context, but I see your point.

      – Superlokkus
      20 mins ago



















    • I think your answer is not complete, one could also think about the "Built-in comma operator The comma operator expressions have the form E1 , E2 In a comma expression E1, E2, the expression E1 is evaluated, its result is discarded " en.cppreference.com/w/cpp/language/operator_other

      – Superlokkus
      1 hour ago






    • 3





      The comma operator can be used as part of an expression, but the code proposed here syntactically isn’t an expression (it’s a statement), so I don’t think there’s a need to look at the comma operator in refuting that this is syntactically correct.

      – templatetypedef
      1 hour ago











    • @templatetypedef It's hard to reason about grammatically incorrect statements, I was trying to cover all cases one could think of when seeing a comma in such context, but I see your point.

      – Superlokkus
      20 mins ago

















    I think your answer is not complete, one could also think about the "Built-in comma operator The comma operator expressions have the form E1 , E2 In a comma expression E1, E2, the expression E1 is evaluated, its result is discarded " en.cppreference.com/w/cpp/language/operator_other

    – Superlokkus
    1 hour ago





    I think your answer is not complete, one could also think about the "Built-in comma operator The comma operator expressions have the form E1 , E2 In a comma expression E1, E2, the expression E1 is evaluated, its result is discarded " en.cppreference.com/w/cpp/language/operator_other

    – Superlokkus
    1 hour ago




    3




    3





    The comma operator can be used as part of an expression, but the code proposed here syntactically isn’t an expression (it’s a statement), so I don’t think there’s a need to look at the comma operator in refuting that this is syntactically correct.

    – templatetypedef
    1 hour ago





    The comma operator can be used as part of an expression, but the code proposed here syntactically isn’t an expression (it’s a statement), so I don’t think there’s a need to look at the comma operator in refuting that this is syntactically correct.

    – templatetypedef
    1 hour ago













    @templatetypedef It's hard to reason about grammatically incorrect statements, I was trying to cover all cases one could think of when seeing a comma in such context, but I see your point.

    – Superlokkus
    20 mins ago





    @templatetypedef It's hard to reason about grammatically incorrect statements, I was trying to cover all cases one could think of when seeing a comma in such context, but I see your point.

    – Superlokkus
    20 mins ago













    2














    By reading the ISO C++14 draft N4140 Annex A [gram], I'm pretty sure it's incorrect since I cant find a way to deduce the grammar from a translation unit from




    translation-unit -> declaration-seq -> declaration -> block-declaration | function-definition | linkage-specification | ...



    function-definition: attribute-specifier-seqopt decl-specifier-seqopt
    declarator virt-specifier-seqopt function-body



    declarator: ptr-declarator noptr-declarator parameters-and-qualifiers
    trailing-return-type




    But your line is more the comma operator but its grammar is:




    expression:
    assignment-expression | expression , assignment-expression



    assignment-expression: conditional-expression | logical-or-expression |
    assignment-operator | initializer-clause | throw-expression




    And there is no way from assignment-expression to function-definition



    Update:
    Thanks to Barry, another way to try to buttom-up parse your text is by rather try to get from a init-declarator-list (which you can get from block-declaration) to a function-definition:




    init-declarator-list: init-declarator | init-declarator-list ,
    init-declarator



    init-declarator: declarator initializeropt




    And




    declarator: ptr-declarator noptr-declarator parameters-and-qualifiers
    trailing-return-type




    Would allow you a function declaration but not definition. So this odd code would be legal:



    #include <string>
    using std::string;

    string r, longestDigitsPrefix(string s);

    string longestDigitsPrefix(string s) {
    for(auto const c : s)
    {
    if(isdigit(c))
    r += c;
    else
    break;
    }
    return r;
    }

    int main(int argc, char *argv) {
    longestDigitsPrefix("foo");

    return 0;
    }


    However I could be wrong, since I'm not used to use the formal grammar of C++, which is normal since it's grammar is very complex, and has some non trivial behaviour.






    share|improve this answer






























      2














      By reading the ISO C++14 draft N4140 Annex A [gram], I'm pretty sure it's incorrect since I cant find a way to deduce the grammar from a translation unit from




      translation-unit -> declaration-seq -> declaration -> block-declaration | function-definition | linkage-specification | ...



      function-definition: attribute-specifier-seqopt decl-specifier-seqopt
      declarator virt-specifier-seqopt function-body



      declarator: ptr-declarator noptr-declarator parameters-and-qualifiers
      trailing-return-type




      But your line is more the comma operator but its grammar is:




      expression:
      assignment-expression | expression , assignment-expression



      assignment-expression: conditional-expression | logical-or-expression |
      assignment-operator | initializer-clause | throw-expression




      And there is no way from assignment-expression to function-definition



      Update:
      Thanks to Barry, another way to try to buttom-up parse your text is by rather try to get from a init-declarator-list (which you can get from block-declaration) to a function-definition:




      init-declarator-list: init-declarator | init-declarator-list ,
      init-declarator



      init-declarator: declarator initializeropt




      And




      declarator: ptr-declarator noptr-declarator parameters-and-qualifiers
      trailing-return-type




      Would allow you a function declaration but not definition. So this odd code would be legal:



      #include <string>
      using std::string;

      string r, longestDigitsPrefix(string s);

      string longestDigitsPrefix(string s) {
      for(auto const c : s)
      {
      if(isdigit(c))
      r += c;
      else
      break;
      }
      return r;
      }

      int main(int argc, char *argv) {
      longestDigitsPrefix("foo");

      return 0;
      }


      However I could be wrong, since I'm not used to use the formal grammar of C++, which is normal since it's grammar is very complex, and has some non trivial behaviour.






      share|improve this answer




























        2












        2








        2







        By reading the ISO C++14 draft N4140 Annex A [gram], I'm pretty sure it's incorrect since I cant find a way to deduce the grammar from a translation unit from




        translation-unit -> declaration-seq -> declaration -> block-declaration | function-definition | linkage-specification | ...



        function-definition: attribute-specifier-seqopt decl-specifier-seqopt
        declarator virt-specifier-seqopt function-body



        declarator: ptr-declarator noptr-declarator parameters-and-qualifiers
        trailing-return-type




        But your line is more the comma operator but its grammar is:




        expression:
        assignment-expression | expression , assignment-expression



        assignment-expression: conditional-expression | logical-or-expression |
        assignment-operator | initializer-clause | throw-expression




        And there is no way from assignment-expression to function-definition



        Update:
        Thanks to Barry, another way to try to buttom-up parse your text is by rather try to get from a init-declarator-list (which you can get from block-declaration) to a function-definition:




        init-declarator-list: init-declarator | init-declarator-list ,
        init-declarator



        init-declarator: declarator initializeropt




        And




        declarator: ptr-declarator noptr-declarator parameters-and-qualifiers
        trailing-return-type




        Would allow you a function declaration but not definition. So this odd code would be legal:



        #include <string>
        using std::string;

        string r, longestDigitsPrefix(string s);

        string longestDigitsPrefix(string s) {
        for(auto const c : s)
        {
        if(isdigit(c))
        r += c;
        else
        break;
        }
        return r;
        }

        int main(int argc, char *argv) {
        longestDigitsPrefix("foo");

        return 0;
        }


        However I could be wrong, since I'm not used to use the formal grammar of C++, which is normal since it's grammar is very complex, and has some non trivial behaviour.






        share|improve this answer















        By reading the ISO C++14 draft N4140 Annex A [gram], I'm pretty sure it's incorrect since I cant find a way to deduce the grammar from a translation unit from




        translation-unit -> declaration-seq -> declaration -> block-declaration | function-definition | linkage-specification | ...



        function-definition: attribute-specifier-seqopt decl-specifier-seqopt
        declarator virt-specifier-seqopt function-body



        declarator: ptr-declarator noptr-declarator parameters-and-qualifiers
        trailing-return-type




        But your line is more the comma operator but its grammar is:




        expression:
        assignment-expression | expression , assignment-expression



        assignment-expression: conditional-expression | logical-or-expression |
        assignment-operator | initializer-clause | throw-expression




        And there is no way from assignment-expression to function-definition



        Update:
        Thanks to Barry, another way to try to buttom-up parse your text is by rather try to get from a init-declarator-list (which you can get from block-declaration) to a function-definition:




        init-declarator-list: init-declarator | init-declarator-list ,
        init-declarator



        init-declarator: declarator initializeropt




        And




        declarator: ptr-declarator noptr-declarator parameters-and-qualifiers
        trailing-return-type




        Would allow you a function declaration but not definition. So this odd code would be legal:



        #include <string>
        using std::string;

        string r, longestDigitsPrefix(string s);

        string longestDigitsPrefix(string s) {
        for(auto const c : s)
        {
        if(isdigit(c))
        r += c;
        else
        break;
        }
        return r;
        }

        int main(int argc, char *argv) {
        longestDigitsPrefix("foo");

        return 0;
        }


        However I could be wrong, since I'm not used to use the formal grammar of C++, which is normal since it's grammar is very complex, and has some non trivial behaviour.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited 1 hour ago

























        answered 1 hour ago









        SuperlokkusSuperlokkus

        1,644833




        1,644833























            -1














            To my knowledge, this is not a valid function declaration.



            The prefix in functions can be used only as a way to define what type is the function's "returning" variable, not the variable itself.



            You can however declare a variable outside your function (thus making it global) and modify it inside the function, as you may have probably attempted, but then you need to pass said variable as a reference in your function's arguments. You would also need to set your function as void, since it is not going to return the variable, but just modify it



            Example



            std::string foo = "Hello";

            void foo_func(std::string &string)
            { //do something with the string
            }

            //call the function and modify the global "foo" string
            foo_func(foo);





            share|improve this answer
























            • As the question has a language-lawyer tag, we expect answers with C++ standard quotes.

              – Matthieu Brucher
              22 mins ago


















            -1














            To my knowledge, this is not a valid function declaration.



            The prefix in functions can be used only as a way to define what type is the function's "returning" variable, not the variable itself.



            You can however declare a variable outside your function (thus making it global) and modify it inside the function, as you may have probably attempted, but then you need to pass said variable as a reference in your function's arguments. You would also need to set your function as void, since it is not going to return the variable, but just modify it



            Example



            std::string foo = "Hello";

            void foo_func(std::string &string)
            { //do something with the string
            }

            //call the function and modify the global "foo" string
            foo_func(foo);





            share|improve this answer
























            • As the question has a language-lawyer tag, we expect answers with C++ standard quotes.

              – Matthieu Brucher
              22 mins ago
















            -1












            -1








            -1







            To my knowledge, this is not a valid function declaration.



            The prefix in functions can be used only as a way to define what type is the function's "returning" variable, not the variable itself.



            You can however declare a variable outside your function (thus making it global) and modify it inside the function, as you may have probably attempted, but then you need to pass said variable as a reference in your function's arguments. You would also need to set your function as void, since it is not going to return the variable, but just modify it



            Example



            std::string foo = "Hello";

            void foo_func(std::string &string)
            { //do something with the string
            }

            //call the function and modify the global "foo" string
            foo_func(foo);





            share|improve this answer













            To my knowledge, this is not a valid function declaration.



            The prefix in functions can be used only as a way to define what type is the function's "returning" variable, not the variable itself.



            You can however declare a variable outside your function (thus making it global) and modify it inside the function, as you may have probably attempted, but then you need to pass said variable as a reference in your function's arguments. You would also need to set your function as void, since it is not going to return the variable, but just modify it



            Example



            std::string foo = "Hello";

            void foo_func(std::string &string)
            { //do something with the string
            }

            //call the function and modify the global "foo" string
            foo_func(foo);






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered 2 hours ago









            Cyber-WaspCyber-Wasp

            308




            308













            • As the question has a language-lawyer tag, we expect answers with C++ standard quotes.

              – Matthieu Brucher
              22 mins ago





















            • As the question has a language-lawyer tag, we expect answers with C++ standard quotes.

              – Matthieu Brucher
              22 mins ago



















            As the question has a language-lawyer tag, we expect answers with C++ standard quotes.

            – Matthieu Brucher
            22 mins ago







            As the question has a language-lawyer tag, we expect answers with C++ standard quotes.

            – Matthieu Brucher
            22 mins ago













            -1














            Why wouldn't it be possible? After all, it's just two declarations with strings, and they can be grouped. There are examples like this in the cppreference page for declarations; they just lack function bodies.



            My g++ (GCC) 8.2.1 allows this within a class. This will compile without warning (-Wall) and return 42.



            struct Weird {
            int r, getR() {return r;};
            };

            int main() {
            Weird w={42};
            return w.getR();
            }





            share|improve this answer





















            • 1





              That's the point, they lack function bodies. Here there is a body, and that's the main difference. Also the case that works is different from OP.

              – Matthieu Brucher
              1 hour ago











            • GCC won't accept this when outside a class. Even inside a class this is invalid code, and it isn't allowed by clang.

              – interjay
              59 mins ago
















            -1














            Why wouldn't it be possible? After all, it's just two declarations with strings, and they can be grouped. There are examples like this in the cppreference page for declarations; they just lack function bodies.



            My g++ (GCC) 8.2.1 allows this within a class. This will compile without warning (-Wall) and return 42.



            struct Weird {
            int r, getR() {return r;};
            };

            int main() {
            Weird w={42};
            return w.getR();
            }





            share|improve this answer





















            • 1





              That's the point, they lack function bodies. Here there is a body, and that's the main difference. Also the case that works is different from OP.

              – Matthieu Brucher
              1 hour ago











            • GCC won't accept this when outside a class. Even inside a class this is invalid code, and it isn't allowed by clang.

              – interjay
              59 mins ago














            -1












            -1








            -1







            Why wouldn't it be possible? After all, it's just two declarations with strings, and they can be grouped. There are examples like this in the cppreference page for declarations; they just lack function bodies.



            My g++ (GCC) 8.2.1 allows this within a class. This will compile without warning (-Wall) and return 42.



            struct Weird {
            int r, getR() {return r;};
            };

            int main() {
            Weird w={42};
            return w.getR();
            }





            share|improve this answer















            Why wouldn't it be possible? After all, it's just two declarations with strings, and they can be grouped. There are examples like this in the cppreference page for declarations; they just lack function bodies.



            My g++ (GCC) 8.2.1 allows this within a class. This will compile without warning (-Wall) and return 42.



            struct Weird {
            int r, getR() {return r;};
            };

            int main() {
            Weird w={42};
            return w.getR();
            }






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited 1 hour ago









            Peter Mortensen

            13.5k1984111




            13.5k1984111










            answered 2 hours ago









            GamificationGamification

            307110




            307110








            • 1





              That's the point, they lack function bodies. Here there is a body, and that's the main difference. Also the case that works is different from OP.

              – Matthieu Brucher
              1 hour ago











            • GCC won't accept this when outside a class. Even inside a class this is invalid code, and it isn't allowed by clang.

              – interjay
              59 mins ago














            • 1





              That's the point, they lack function bodies. Here there is a body, and that's the main difference. Also the case that works is different from OP.

              – Matthieu Brucher
              1 hour ago











            • GCC won't accept this when outside a class. Even inside a class this is invalid code, and it isn't allowed by clang.

              – interjay
              59 mins ago








            1




            1





            That's the point, they lack function bodies. Here there is a body, and that's the main difference. Also the case that works is different from OP.

            – Matthieu Brucher
            1 hour ago





            That's the point, they lack function bodies. Here there is a body, and that's the main difference. Also the case that works is different from OP.

            – Matthieu Brucher
            1 hour ago













            GCC won't accept this when outside a class. Even inside a class this is invalid code, and it isn't allowed by clang.

            – interjay
            59 mins ago





            GCC won't accept this when outside a class. Even inside a class this is invalid code, and it isn't allowed by clang.

            – interjay
            59 mins ago











            -3














            This code combines a variable declaration with a function declaration. The function uses the (global) variable and returns its value eventually. No, I don't think this kind of code is usual C++ although it is formally valid.






            share|improve this answer



















            • 1





              Can you show a compiler that accept this? If it's a global variable, then it misses the return type?

              – Matthieu Brucher
              2 hours ago











            • The return type is 'string'.

              – another-dave
              2 hours ago











            • string r, s; should not be surprising. Neither should be string r, *s;, although it's IMHO bad style. So, why is string r, function() {return r;}; surprising?

              – Ulrich Eckhardt
              2 hours ago






            • 3





              Yes, the return type is string, but only valid if there is a prototype. The function definition like OP's code doesn't work.

              – Matthieu Brucher
              2 hours ago
















            -3














            This code combines a variable declaration with a function declaration. The function uses the (global) variable and returns its value eventually. No, I don't think this kind of code is usual C++ although it is formally valid.






            share|improve this answer



















            • 1





              Can you show a compiler that accept this? If it's a global variable, then it misses the return type?

              – Matthieu Brucher
              2 hours ago











            • The return type is 'string'.

              – another-dave
              2 hours ago











            • string r, s; should not be surprising. Neither should be string r, *s;, although it's IMHO bad style. So, why is string r, function() {return r;}; surprising?

              – Ulrich Eckhardt
              2 hours ago






            • 3





              Yes, the return type is string, but only valid if there is a prototype. The function definition like OP's code doesn't work.

              – Matthieu Brucher
              2 hours ago














            -3












            -3








            -3







            This code combines a variable declaration with a function declaration. The function uses the (global) variable and returns its value eventually. No, I don't think this kind of code is usual C++ although it is formally valid.






            share|improve this answer













            This code combines a variable declaration with a function declaration. The function uses the (global) variable and returns its value eventually. No, I don't think this kind of code is usual C++ although it is formally valid.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered 2 hours ago









            Ulrich EckhardtUlrich Eckhardt

            12.7k11736




            12.7k11736








            • 1





              Can you show a compiler that accept this? If it's a global variable, then it misses the return type?

              – Matthieu Brucher
              2 hours ago











            • The return type is 'string'.

              – another-dave
              2 hours ago











            • string r, s; should not be surprising. Neither should be string r, *s;, although it's IMHO bad style. So, why is string r, function() {return r;}; surprising?

              – Ulrich Eckhardt
              2 hours ago






            • 3





              Yes, the return type is string, but only valid if there is a prototype. The function definition like OP's code doesn't work.

              – Matthieu Brucher
              2 hours ago














            • 1





              Can you show a compiler that accept this? If it's a global variable, then it misses the return type?

              – Matthieu Brucher
              2 hours ago











            • The return type is 'string'.

              – another-dave
              2 hours ago











            • string r, s; should not be surprising. Neither should be string r, *s;, although it's IMHO bad style. So, why is string r, function() {return r;}; surprising?

              – Ulrich Eckhardt
              2 hours ago






            • 3





              Yes, the return type is string, but only valid if there is a prototype. The function definition like OP's code doesn't work.

              – Matthieu Brucher
              2 hours ago








            1




            1





            Can you show a compiler that accept this? If it's a global variable, then it misses the return type?

            – Matthieu Brucher
            2 hours ago





            Can you show a compiler that accept this? If it's a global variable, then it misses the return type?

            – Matthieu Brucher
            2 hours ago













            The return type is 'string'.

            – another-dave
            2 hours ago





            The return type is 'string'.

            – another-dave
            2 hours ago













            string r, s; should not be surprising. Neither should be string r, *s;, although it's IMHO bad style. So, why is string r, function() {return r;}; surprising?

            – Ulrich Eckhardt
            2 hours ago





            string r, s; should not be surprising. Neither should be string r, *s;, although it's IMHO bad style. So, why is string r, function() {return r;}; surprising?

            – Ulrich Eckhardt
            2 hours ago




            3




            3





            Yes, the return type is string, but only valid if there is a prototype. The function definition like OP's code doesn't work.

            – Matthieu Brucher
            2 hours ago





            Yes, the return type is string, but only valid if there is a prototype. The function definition like OP's code doesn't work.

            – Matthieu Brucher
            2 hours ago


















            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%2f54277381%2fdefining-a-return-variable-in-the-function-declaration-is-this-legitimate-in-mo%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

            How to label and detect the document text images

            Vallis Paradisi

            Tabula Rosettana