0

I'm learning c++ from HackerRank and this is some of their codes in int main():

    int a, b;
    int *pa = &a, *pb = &b;
    
    scanf("%d %d", &a, &b);
    update(pa, pb);
    printf("%d\n%d", a, b);

why do you need to use &a and &b for scanf? I remember I have done it with the actual variables and it worked fine.

imanoob
  • 47
  • 7
  • 4
    It's not just `scanf`. Functions that need to modify variables in the caller must receive references (or pointers) to those variables as arguments. Otherwise arguments are passed by value, and the called function receives only a copy of the value. – dxiv May 07 '21 at 03:11
  • 4
    This is more of a C example. C++ has reference types so that a call like `func(var)` can actually modify the value of `var`. In C this is not possible. – Nate Eldredge May 07 '21 at 03:12
  • 4
    _"I'm learning C++ from HackerRank and this is some of their codes"_ looks like they're teaching C. I wouldn't normally choose a C standard library function over the nicer C++ standard library abstractions for I/O. – Patrick Roberts May 07 '21 at 03:13
  • 3
    In general competition sites like HackerRank are not intended to teach anyone how to program. As a result they're pretty bad at it. Some are awesomely bad at it. We see folks coming through here regularly with their code all ed up by garbage they learned from trying to ape what they see in competition code. When competing you cheat like hell to eke out that last little bit of performance that puts you ahead of your rivals. – user4581301 May 07 '21 at 03:32
  • In order to do that you need to know a LOT about the language rules , groovy math tricks, and minute details about the compiler and underlying hardware so you will know how all of the abusive rule-breaking you're about to do will be interpreted by the compiler and will execute on the hardware. Learn to program from [a good book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). Then use HackerRank for fun or for a little bit of practice. Personally I believe that hooking up with a quality open source project is going to be better practice. – user4581301 May 07 '21 at 03:32
  • This is pass-by-address, not pass-by-value. If it was pass-by-value, `scanf()` couldn't modify the actual parameters you pass. This is rather basic. There is no such thing as 'learning C++ from HackerRank', and your question is entirely about C, not C++. – user207421 May 07 '21 at 03:59

1 Answers1

4

To be clear, you're not "passing by reference" in the C++ definition here. You're passing a pointer to your values to scanf. C++ pass-by-reference is declared on the callee side, and happens implicitly on the caller side; the caller doesn't need to, and usually can't, use the & (address-of) operator at all (not without undoing it in the same expression).

In any event, if you pass the raw values to scanf, it receives a copy of the value, not a reference or pointer to it (scanf is a C function that was inherited by C++; it can't receive C++ references at all), and has no idea where it came from, so it can't find your a and b to write to.

Worse, it tries to interpret the value it received as a pointer to where it should write the parsed value, which is highly likely to cause a segfault as it tries to write to unallocated memory (if you're unlucky, it writes to some random valid memory address and now you've got subtle memory corruption issues lurking in your code instead of obvious crashes).

Note: If by "done it with actual variables" you mean you passed pa and pb instead of &a and &b, that would work just fine, since pa stores the same pointer &a produces, and scanf just needs the pointer, it doesn't care where it comes from; they're interchangeable here (they may or may not be for update, depending on whether update receives pointers, or pointer references).

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
  • The last paragraph touches on one of the great horrors of programming: Sometimes doing things wrong can look like they worked. And they can go on looking like they worked for a very long time. And then, usually at the worst possible time, it doesn't work. – user4581301 May 07 '21 at 03:38
  • 1
    @user4581301: Sorry, edited to add another paragraph. For future readers, user4581301 is referring specifically to my comment noting how you're actually lucky if you die loudly with a segfault, since the alternative is almost certainly a subtle memory corruption issue that will bite you in unexpected and often hard to reproduce ways. – ShadowRanger May 07 '21 at 03:45