|
|
Exercise
15.8
Write a standards-conforming C++ program
containing a sequence of at least ten different consecutive keywords not
separated by identifiers, operators, punctutation characters, etc. |
|
One
way of interpreting this question is to say that alternative tokens such
as bit_or are keywords. If we could in addition repeat such tokens,
you would quickly come up with arbitrarily long sequences of keywords:
int main() {
bool result = true and true and true
and true and not false;
}
Many may consider
this cheating either on the grounds that a keyword is being repeated or
that it is in fact not a keyword but an "alternative token" (the distinction
is thin however, and you will note that Bjarne treats such tokens as keywords
in par. A.2.) Another, perhaps more obscure, repeatable keyword (not an
alternative token this time!) is sizeof:
int main() {
return sizeof sizeof sizeof sizeof
sizeof sizeof
sizeof sizeof true;
}
|
|
Coming
up with an uninterrupted sequence of distinct, honest-to-goodness keywords
is a little harder. A good way to start is to stare at the table of all
keywords (see e.g. par. A.2 in Bjarne's book). The most interesting candidate
keywords are those that are not required to be surrounded by punctuation:
const
(par.
5.4), inline (par. 7.1.1) and new (par 6.2.6) could potentially
be useful. On the other hand static_cast (par. 6.2.7) or private
(par. 15.3) are less flexible because they are always followed by a non-keyword
token ('<' and ':' respectively.)
Declarations can have a fair number of keywords. Here is a good starting
point:
signed long int const volatile a;
Maybe I hear you say "You can add extern to that" (par. 9.2) or
perhaps "Make it the return-type of a function and add qualifiers"? Good
idea:
extern inline signed long int const volatile f();
Ah, and we could explicitly instantiate a template (par. C.13.10)... and
it could be an operator (chap. 11):
template
extern inline signed long int const volatile operator*(X&);
Nine keywords... very close...
In fact, if you allow "alternative tokens", you can have ten!
template
extern inline signed long int const volatile
operator and(X&, Y&);
|
|
So,
mission accomplished as far as the spirit of the exercise goes, but for
brainteasing's sake, let's look for a solution not involving alternative
tokens. Some expressions can contain little pieces of declaration-like
items (types). The typeid (par. 15.4.4) and sizeof (par.
4.6) operators are like that, but they require parentheses. The new
operator (par. 6.2.6) does not have that restriction, so that is useful.
Remember also that the sizeof
operator doesn't require parentheses
either if its argument is an expression instead of a type. Combining the
two, we get:
sizeof new signed long int const volatile();
Seven only, but the expression can be grown with the throw operator
(par. 8.3.1), so we are eight!
After that it may not be possible to grow the expression anymore, but
some statements (par. 6.3) have keywords that are followed by expressions
without intervening punctuation. If you look closely at the table in par.
6.3 of The C++ Programming Language, you will find that the do
and else keywords are like that. So our final answer is:
int main() {
if (false) {
} else do
throw sizeof new signed long int
const volatile();
while (false);
}
Clearly, this
is not very useful code and indeed it is fair to say that useful code will
never need to have ten consecutive distinct keywords in C++. However, this
is a great bit of trivia to impress your friends and/or colleagues, and
coming up with the solution got me to explore the C++ grammar in some more
detail.
Ah yes, and you cannot do this in C ;-)
Finally, we
should mention the following clever trick sent in by “Prince Vijay Daniel”:
#define keywords this unsigned class struct \
enum template if for namespace else do return \
throw sizeof new signed long
We could list all the C++ keywords this way. However, we should also note
that identifiers only become keywords after preprocessing, and therefore
this latter solution does not quite fit the spirit of the exercise.
|
|
Many
Thanks to Bjarne Stroustrup,
Andrew Koenig and “Gargantua Blargg” for their suggestions and corrections.
The
eleven
distinct wholesome keywords challenge has been solved. “Gargantua
Blargg” not only came up with that answer,
but also shows how you can have twenty (yes, 20) different "extended" keywords
placed in a valid C++ sequence ("extended" meaning that alternative tokens
are included.) And Anatoli Tubman upped that to 24 keywords...
So now the new challenge is for twelve classic
keywords or 25 extended keywords.
E-mail me if you know! |
|
|