Well, for the specific case of a string literal, you can do:
const char* psz = "This is a constant string";
or
char[] asz = "This is a non-const literal string";
A few things.
First, I was under the impression that we were discussing the "const"
keyword as it applies to function declarations. The above are examples of
"const"-declared constants, which C# does already have, and so aren't
really what we were talking about.
Second, in the above example, the second line of code doesn't compile.
You can fix the syntax error, by putting the [] in the right place (after
the "asz" rather than after the "char"), but then the type of the variable
is not the same as the first line of code. You can't compare the results
of the two, because you're changing more than just the "const"-ness.
Third, if make the two lines of code actually comparable, by fixing the
type in the second line of code to be "char*", you'll find that it
compiles to exactly the same instructions as the first line of code. In
other words, any difference between the two lines of code you posted (once
you fix it so that it compiles) are caused *not* by the use of the "const"
keyword, but rather by the differences in the way the compiler deals with
a pointer versus an array.
The second form requires the compiler to actually initialize the memory
on every entry to the function, instead of referencing a string
literal. It
also prevents string folding, which increases the size of the binary,
which has its own set of performance problems.
See above. Any such problems are not due to the difference between
something being "const" and not "const". (Though, actually...I looked at
the code generated and while it's true the array is initialized
differently than the pointer, that initialization does not actually
involve initializing the storage for the array itself...in other words,
it's not like the string literal gets copied).
Beyond that, pass-by-const reference is more performant than
pass-by-value for large data types. Sure, you don't strictly need
const for that, you can pass by reference and get most of the
performance gains.
You don't even not strictly need const for that. The use of the "const"
keyword has nothing do with whether you can pass things by reference or
not. It makes it safer (which *is* the point of using "const"), but you
can pass things by reference just fine without using "const". In other
words, in that example, "const" doesn't improve performance, it improves
safety.
I certainly wouldn't try to disagree with the statement that "const"
improves safety. But that's not the question here.
But, const also enables a lot of optimizations:
reuse of temporaries
constructor elision
improved alias analysis
elimination of variable access
loop unrolling
As applied to function declarations, I don't see how "const" enables any
of those optimizations. The compiler can't rely on the "const" keyword,
because it can always wind up being cast away.
For an example:
const int nibbleCount = sizeof (int) * 2;
char formatted[nibbleCount + 1] = { 0 };
char* ToHex(int n)
{
for( int i = 0; i < nibbleCount; i++ )
{
formatted[nibbleCount - i] = 0x30 + ((n >> (4 * i)) & 0x0f);
if (formatted[nibbleCount - i] > '9') formatted[nibbleCount - i] +=
'a' - '0' - 10;
}
}
Take out the const, and the snippet won't even compile... and if it did,
the compiler couldn't unroll the loop. With a constant value of
nibbleCount,
however, the compiler can remove the loop entirely, eliminate the
variable i, and start using specialized instructions for accessing the
different
bytes of the input.
Well, first of all, that code won't compile regardless. You've got a
function that is supposed to return a value, but it doesn't.
Secondly, the reason taking "const" out prevents it from compiling is that
you can't initialize an array with a size that isn't known at compile
time. And of course, likewise the compiler can't make optimizations
requiring constant values based on non-constant values.
For example, these two functions wind up compiled to be very different:
const int i = 5;
void Test1()
{
printf("%d", i);
}
int j = 5;
void Test2()
{
printf("%d", j);
}
I certainly don't debate that. But the reason they are different is
because in the first case, the value of the variable is known at compile
time, while the value of the variable in the second case is not. This has
exactly nothing to do with the question of using "const" in a function
declaration.
I thought maybe you had an example of how including "const" for function
declarations in C# would help optimizations. After all, C# already has
"const" for variable declarations, and it has the same benefits in C# as
it has in C++. So there's not really any point in contrasting the two
languages in that way. So far, you haven't provided any actual examples
of performance improvements that using "const" in a function declaration
would enable.
Pete