0

This test actually passes, it seems that the size of the destination doesn't matter, as long as it is a valid pointer to a char array.

I actually expected the test to fail, any explanation would be appreciated.

#include "gtest/gtest.h"

#include <string>

using namespace std;

TEST(practice, book) {
    const char * copyFrom = "Hello World!";
    char copyTo[0]; //TODO: why it works?

    std::strcpy(copyTo, copyFrom);

    EXPECT_STREQ("Hello World!", copyTo);

    std::cout << copyTo << std::endl;
}
jnj
  • 755
  • 2
  • 11
  • 23
  • 1
    When code has a bug like this, it often doesn't do what you expect. That's why it's important to *avoid* bugs like this. I would also note that your comment in the code says that "it works". Why would you describe behavior you don't expect as the code working? Generally, we say that code works when it does what we expect, not when it does something different from what we expect. – David Schwartz Jun 23 '19 at 00:21
  • 1
    Also note `char copyTo[0];` is not a valid definition in the first place: raw arrays with size zero are not allowed. – aschepler Jun 23 '19 at 01:02

2 Answers2

1

I actually expected the test to fail

Why?

A failure of any sort would mean one of two things:

  • crash due to undefined behaviour

  • other error raised by std::strcpy which performed some checks on its arguments

std::strcpy does not perform any checks on its arguments (due to performance reasons) and it explicitly states that it's undefined behaviour to try to use it to write to a not large enough buffer. That means that a crash (or other signs of a failure) might as well happen, but due to undefined behaviour, not due to some diagnostics that determined the buffer incorrectness.

[...] it seems that the size of the destination doesn't matter, as long as it is a valid pointer to a char array

For the code to compile and run? Yes. For the code to be well-formed? No.

Your code exhibits undefined behaviour and one can't predict its outcome. It may seem to work, it may crash, it may seem to work only on fridays or it can start outputting stuff to stdout infinitely.

Remember - you can't expect anything from a code that exhibits undefined behaviour.

Fureeish
  • 12,533
  • 4
  • 32
  • 62
1

It doesn't work. Or maybe it does. Undefined Behavior (UB) is like that, allowing anything at all to happen.


Anyway, a raw array must have a positive size, which is one of the reasons std::array was introduced. If your compiler allows zero-sized arrays as an extension, that's outside the standard.

Still, assuming a zero-sized array really has 0 elements, accessing any member is UB.

And as std::strcpy() blindly trusts that second argument points to a string, and the first to a buffer of sufficient size to store a copy including the terminating null, you are obviously writing more than zero elements.

As an aside, you have to include <cstring>, and shouldn't using namespace std;.

Deduplicator
  • 44,692
  • 7
  • 66
  • 118