1

All C code:

Why is this allowed:

int main()
{
    const int *i;
    int j=2;

    i=&j;
}

But not this:

int main()
{
    const int i;
    int j=2;

    i=j;
}

Is there a way to declare a local constant variable and then define it elsewhere within the scope? The first case that uses a pointer is unreliable because I can get away with defining it multiple times, defeating the purpose of the constant keyword in the first place.

Sanfer
  • 414
  • 5
  • 16

2 Answers2

1

const int *i means that the int pointed to by i is const, so you can't do *i = j. But const int i means i itself is const so you must declare it like const int i = 2; and then it remains const and can't be touched.

The difference is what you change. If you have a const integer - it can't be changed, if you have a pointer to const integer - and the pointer is not const, well, that pointer can be assigned to point to whatever int you would like.

To answer your question: no, you can't define a const int and then redefine it. That negates the meaning of const.

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
CIsForCookies
  • 12,097
  • 11
  • 59
  • 124
  • No kidding. But my question was if I can 'declare' and then define, not define and then define. As in assign a type first and then later on assign a value. – Sanfer Jun 06 '15 at 22:30
  • 1
    Spelling "you" as "u" makes your answer more difficult to read. – Keith Thompson Jun 06 '15 at 23:33
  • What bout this http://stackoverflow.com/questions/3669315/is-there-some-ninja-trick-to-make-a-variable-constant-after-its-declaration – CIsForCookies Jun 06 '15 at 23:35
  • @Sanfer all declarations of variables inside a scope are also definitions, there's no such thing as "forward declaration of a variable" or whatever, in a scope. (There is such a thing for global variables) – M.M Jun 07 '15 at 01:03
1

Semantically the first example means "a pointer to a const int" not "a const pointer to an int".

So, when you set i to point to j (a non-const int). i now points to a const, as such you can't change the value of j through the pointer i, for example:

int main()
{
    const int *i;
    int j=2;

    i=&j;

    *i = 4;
}

Won't compile, giving the error "assignment of read-only location ‘*i’". So the pointer restricts your access to the value being pointed to. But the pointer itself can still be changed.

C being the language that it is, doesn't really offer much protection and you can often throw away the const and assign the variable a new value anyway e.g.:

#include <stdio.h>

void assign(int *a) {
  *a=5;
}

int main()
{
    int const i=1;
    int j=2;
    assign((int *) &i);
    printf("i: %d\n",i);
}

But I'm not sure I'd recommend it. And while this works in some versions of gcc, this behavior is likely undefined in the C standard.

new299
  • 804
  • 1
  • 7
  • 17
  • Thanks, your first sentence explained it all. But is there a way to declare a const variable and then define it later? It seems silly to not have a way to do that. – Sanfer Jun 06 '15 at 22:34
  • @Sanfer Well, I don't believe you can do exactly want you want. But const in C generally doesn't provide much protection and you can often recast a const variable as a non-const and modify it. I've updated the above with an example. – new299 Jun 06 '15 at 23:31
  • Nice this is the answer I needed thanks. I'm going to do it anyway because 1) style because its nice to have all the variables declared first and then defined/manipulated later 2) the need to use a function for constant assignment prevents accidental i=4; kinds of things, which was what I intended for in the first place. – Sanfer Jun 07 '15 at 00:37
  • Your second example causes undefined behaviour, I'm not sure what it is supposed to illustrate. You appear to have fooled OP into thinking this is acceptable code – M.M Jun 07 '15 at 00:57
  • @Sanfer it is good style to not declare variables until they are needed. Maybe you are misled by early C code declaring variables at the start of the block; this was because historical compilers could not cope with variables being declared anywhere -- it wasn't a style decision – M.M Jun 07 '15 at 01:02
  • @Matt McNabb the second code snippet of new299 with the void assign(int*) function worked for me, copy and paste. It changes the value of the constant variable by a pointer magic-trick. The books on programming that I have read generally declare their variables at the start of the function before using them. For my peace of mind can you point to a good reference on coding style? I can definitely find a few online but seeing that you are well versed in the matter would reduce my risk of choosing a crappy book. – Sanfer Jun 07 '15 at 07:19
  • @Sanfer C doesn't work that way. It has [undefined behaviour](http://stackoverflow.com/a/4105123/1505939). What *appears* to work for you now might stop working in other circumstances. – M.M Jun 07 '15 at 07:47
  • Sanfer, @matt-mcnabb is technically correct. In particular some platforms might put consts in read only flash, the behavior is likely undefined (though I'd be interested in a link to the standard), which is why I said I wouldn't recommend it. However it's worth noting that const doesn't offer much practical protection in most implementations. It's more of a notational convenience. C has few safety nets. – new299 Jun 07 '15 at 15:37
  • Urm ok. Guess I'll just have to be careful. @Matt McNabb nice link. – Sanfer Jun 08 '15 at 16:46