Defining a return variable in the function declaration. Is this legitimate in modern C++?
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
|
show 1 more comment
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
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 describeddecl a; decl b;
-a
orb
can be function definitions (note the semicolon). But a function definition may not appear indecl 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
|
show 1 more comment
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
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
c++ language-lawyer declaration
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 describeddecl a; decl b;
-a
orb
can be function definitions (note the semicolon). But a function definition may not appear indecl 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
|
show 1 more comment
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 describeddecl a; decl b;
-a
orb
can be function definitions (note the semicolon). But a function definition may not appear indecl 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
|
show 1 more comment
5 Answers
5
active
oldest
votes
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 int
s, c
is a pointer to an array of 10 int
s, 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...
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
add a comment |
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.
add a comment |
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);
As the question has alanguage-lawyer
tag, we expect answers with C++ standard quotes.
– Matthieu Brucher
22 mins ago
add a comment |
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();
}
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
add a comment |
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.
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 bestring r, *s;
, although it's IMHO bad style. So, why isstring 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
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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 int
s, c
is a pointer to an array of 10 int
s, 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...
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
add a comment |
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 int
s, c
is a pointer to an array of 10 int
s, 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...
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
add a comment |
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 int
s, c
is a pointer to an array of 10 int
s, 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...
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 int
s, c
is a pointer to an array of 10 int
s, 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...
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
add a comment |
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
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
edited 1 hour ago
answered 1 hour ago
SuperlokkusSuperlokkus
1,644833
1,644833
add a comment |
add a comment |
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);
As the question has alanguage-lawyer
tag, we expect answers with C++ standard quotes.
– Matthieu Brucher
22 mins ago
add a comment |
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);
As the question has alanguage-lawyer
tag, we expect answers with C++ standard quotes.
– Matthieu Brucher
22 mins ago
add a comment |
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);
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);
answered 2 hours ago
Cyber-WaspCyber-Wasp
308
308
As the question has alanguage-lawyer
tag, we expect answers with C++ standard quotes.
– Matthieu Brucher
22 mins ago
add a comment |
As the question has alanguage-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
add a comment |
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();
}
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
add a comment |
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();
}
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
add a comment |
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();
}
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();
}
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
add a comment |
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
add a comment |
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.
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 bestring r, *s;
, although it's IMHO bad style. So, why isstring 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
add a comment |
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.
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 bestring r, *s;
, although it's IMHO bad style. So, why isstring 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
add a comment |
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.
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.
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 bestring r, *s;
, although it's IMHO bad style. So, why isstring 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
add a comment |
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 bestring r, *s;
, although it's IMHO bad style. So, why isstring 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
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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
orb
can be function definitions (note the semicolon). But a function definition may not appear indecl 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