-3

I know that referencing the address of a registered variable results in a compile error.

int main()
{
    register int i = 10;
    int *a = &i;
    printf("%d", *a);
    getchar();
    return 0;
}

As expected, this gave a compiler error when using gcc because of the reference to the address of registered variable i.

Then how is it that the following code, which does something similar, results in no error?

#include<stdio.h>
int *NEXT(register int i)
{
    int *ipt;
    ipt = &i;
    ipt++;
    return ipt;
}
main ()
{
    int j=2;
    printf("%d",(NEXT(j)));
}

EDIT : My gcc version in

i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00) Copyright (C) 2007 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

aasthetic
  • 327
  • 4
  • 21
  • What is the compiler error you got? – Cory Klein Jun 17 '13 at 19:22
  • http://stackoverflow.com/questions/578202/register-keyword-in-c – Fredrik Pihl Jun 17 '13 at 19:22
  • 2
    @FredrikPihl That isn't relevant to the OP's question. – Jim Balter Jun 17 '13 at 19:23
  • 3
    If you are saying that the 2. example does NOT give an error, I would consider it a gcc bug. (It certainly fails on all the gcc installations I tried.). – nos Jun 17 '13 at 19:25
  • I shall downvote this question simply because you have zero research effort. You had a answer suggestion just by typing that title, yet posted this question anyway. – Havenard Jun 17 '13 at 19:25
  • 2
    What version of gcc are you using? I get: `register.c:5:5: error: address of register variable ‘i’ requested` with gcc version 4.7.2 (Debian 4.7.2-5). – Samuel Edwin Ward Jun 17 '13 at 19:26
  • 1
    @Havenard: I voted up to counter your incorrect vote down. The documentation of the “register” keyword does **not** answer this question. – Eric Postpischil Jun 17 '13 at 19:26
  • @Havenard - can you post a link to the question that duplicates this one? – Cory Klein Jun 17 '13 at 19:29
  • What is the compiler error anyway? Forgot the most important part. – Havenard Jun 17 '13 at 19:30
  • 1
    @richi_18007 The second code example does not compile using `gcc 4.6.3`. It gives me the error `main.c:5:5: error: address of register variable ‘i’ requested`. What compiler and version are you using? – Cory Klein Jun 17 '13 at 19:31
  • 2
    http://gustedt.wordpress.com/2010/08/17/a-common-misconsception-the-register-keyword/ – Jens Gustedt Jun 17 '13 at 19:32
  • 1
    does this even compile ? i am getting error : prog.c: In function ‘NEXT’: prog.c:5:5: error: address of register variable ‘i’ requested. K&R stated rule that address of register cannot be taken!. i think there is a flaw in your code. – S J Jun 17 '13 at 19:32

3 Answers3

10

If your report is accurate, this is either due to a bug in your compiler, or, possibly, a permissive compilation mode in which your compiler does not conform to standard C.

Per C 2011 5.1.1.3, a C implementation must product a diagnostic when a constraint is violated. Per 6.5.3.2, one constraint is that the operand of & must not have been declared with register. Therefore, a conforming compiler is not free to ignore the error in this case; it must produce a diagnostic.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
  • I was using gcc on mac . gcc --version gives me this i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00) Copyright (C) 2007 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. – aasthetic Jun 17 '13 at 21:56
  • @richi_18007: That is a fairly old compiler. The oldest I have is slightly newer, also 4.2.1 but build 5666. It reports an error taking the address of a parameter declared `register`. Newer Apple compilers, including Apple clang 4.0 and Apple LLVM 5.0 also report an error. I can only suppose it was a transitory bug or the compiler is compiling a different source file than you think it is. – Eric Postpischil Jun 17 '13 at 23:34
  • Nevermind, it is now giving me an error. I guess it was a transitory bug or maybe I compiled the wrong source file. – aasthetic Jun 18 '13 at 03:02
4
ipt = &i;

You are taking the address of a register object. The compiler must issue a warning and can stop the compilation if wanted. Which actually means that if your compiler does not issue a warning, the compiler cannot pretend to be a conforming C compiler (C99, 5.1.1.3p1).

Beside that:

printf("%d",(NEXT(j)));

d conversion specifier expects an int but you are passing an int *.

ouah
  • 142,963
  • 15
  • 272
  • 331
  • Please read the question more carefully ... `ipt = &i;` *didn't* get an error; only `int *a = &i;` did. – Jim Balter Jun 17 '13 at 19:25
  • @JimBalter I read again where is the *didn't*? – ouah Jun 17 '13 at 19:25
  • " But how did this work ?" – Jim Balter Jun 17 '13 at 19:26
  • @JimBalter Well what I meant is the question is not very clear. Did you see any error in my answer to downvote it? – ouah Jun 17 '13 at 19:30
  • Yes, I certainly do, but I'm not one of the two people who downvoted it. – Jim Balter Jun 17 '13 at 19:31
  • @JimBalter Could you explain what are the errors in this answer? – ouah Jun 17 '13 at 19:33
  • @JimBalter You do see an error in the answer? Because the two things he writes of are what gcc complains about if you compile the code with `-Wall` – Praetorian Jun 17 '13 at 19:34
  • It doesn't answer the question. The OP wants to know why the code worked. – Jim Balter Jun 17 '13 at 19:34
  • 2
    @ouah: Even if your answer contains true statements, do you think that true statements must be voted up, or not voted down? The guidelines for voting say to judge **usefulness**, not truth or correctness. This answer does not answer the question, which is why the compiler does **not** produce a diagnostic when it apparently should. This “answer” does not give any useful information about that. – Eric Postpischil Jun 17 '13 at 19:35
  • 2
    @EricPostpischil the answer is: if the compiler does not issue a diagnostic well, it's not a conforming C compiler. – ouah Jun 17 '13 at 19:36
  • 2
    @ouah: So write an answer stating that. Since it is not in this answer, this answer remains not useful. – Eric Postpischil Jun 17 '13 at 19:37
  • 2
    @EricPostpischil well I was abruptly stopped in my answer by the downvotes, but I can add this precision. – ouah Jun 17 '13 at 19:39
  • 2
    @JimBalter: I was thinking it is a faulty JavaScript implementation in ouah’s browser. – Eric Postpischil Jun 17 '13 at 19:40
  • Gcc version I am using i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00) Copyright (C) 2007 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. – aasthetic Jun 17 '13 at 21:57
  • @richi_18007 and do you get the warning with `-Wall` – ouah Jun 17 '13 at 22:02
  • Yeah , -Wall -Werrors -pedantic does not let the code go through. Nevermind, it is now giving me an error. I guess it was a transitory bug or maybe I compiled the wrong source file – aasthetic Jun 18 '13 at 03:00
  • @EricPostpischil Notice anything odd here? – Jim Balter Jun 18 '13 at 08:06
-1

A compiler is free to ignore any register directive but taking the address of such a variable is still illegal.

Passing a register variable as a function parameter will, I'm sure, be ignored in all cases unless the function is inlined, as the stack will have to be populated by the function parameters: and a forgiving compiler, such as the one you're using; will emit taking its address.

I want to know if that behaviour is standard though. I'll upvote any answer given by an expert who knows for sure.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • 8
    No, it can't ignore `register`. If the address of a variable declared with it is taken, that's a constraint violation and requires a diagnostic message. – Daniel Fischer Jun 17 '13 at 19:24
  • 1
    Are you sure that's even the case if you have register as one of the function parameters? I think I'm correct here; especially with the older linux compilers. But I'm happy to be told I'm wrong on this point. – Bathsheba Jun 17 '13 at 19:25
  • 1
    Lots of architectures pass arguments in the registers. – Samuel Edwin Ward Jun 17 '13 at 19:27
  • @Bathsheba A C compiler is required to not allow you to take the address of a register variable (yes, even if the compiler doesn't actually place the variable in a register). – nos Jun 17 '13 at 19:29
  • "I want to know if that behaviour is standard though." -- Are you asking questions, or answering them? "I'll upvote any answer given by an expert who knows for sure." -- It doesn't take an "expert", just someone who can read the C standard. – Jim Balter Jun 17 '13 at 19:33
  • @JimBalter To be fair, the standard isn't the most easy reading. – Daniel Fischer Jun 17 '13 at 19:34
  • Too true; and my copy is in the office ;-) Let's bear in mind though that the OP's compiler emits taking the address of i in the function and we postulating why. Still think I'm correct here. – Bathsheba Jun 17 '13 at 19:35
  • @DanielFischer I didn't say it is, nor did I say anything else un"fair". – Jim Balter Jun 17 '13 at 19:36
  • "my copy is in the office" -- it's available on-line. Anyway, if you can't get to a copy, then you should avoid posting an answer. You should certainly not include in your answer chitchat about what you would or wouldn't upvote ... that sort of thing belongs in comments. – Jim Balter Jun 17 '13 at 19:39
  • @JimBalter I didn't mean to imply you said anything unfair. But one could argue that it takes some kind of expert to read the standard, since the language is difficult. – Daniel Fischer Jun 17 '13 at 19:39
  • @DanielFischer Ok, *fair* enough. :-) – Jim Balter Jun 17 '13 at 19:44
  • 2
    @SamuelEdwinWard: Whether the argument is passed via a cpu register has *nothing* to do with whether the object has `register` storage. – R.. GitHub STOP HELPING ICE Jun 17 '13 at 19:53
  • @R..: I didn't mean to say that it did. I was responding to "the stack will have to be populated by the function parameters", which I interpreted to mean that the arguments had to be passed on the stack. – Samuel Edwin Ward Jun 17 '13 at 20:33