-3

Can someone please enlighten me regarding answers in this question Assigning a value to char* in a struct?

In the answers, they told the asker not to mix C and C++, i.e. use string and cin if it's C++ or char if it's C. It makes me confuse since what I know is that we can use like char, printf and so on in C++ by including appropriate libraries. What if we should work with char in C++ project because of several reasons?

One of the answer also tells that typedef struct{...}x; is not necessary in C++, while so far I know now it is used to prevent re-typing struct x, e.g x Name1; x Name2; instead of struct x Name1; struct x Name2;. It is confusing enough for a beginner like me.

ryn
  • 11
  • 1
  • 2
    If you are confused about modern C++ a [good book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) might help. Did you learn C before? Sadly many online tutorials fail to teach proper modern C++ and mix in much (and often simply wrong) C-style code. – Lukas-T Jun 16 '21 at 12:20
  • The code in the linked question really is a broken mix of C and C++. The suggestion to pick one and learn it properly is appropriate. There are also subtle differences between the languages (like the fact that C has a separate namespace for structs, C++ doesn't), you should probably follow the same suggestion. –  Jun 16 '21 at 12:26
  • Actually, I learned C and C++ mostly parallel from online tutorials. And some of them use some C functions in C++, so I think it's fine to use C in C++ for most cases. – ryn Jun 16 '21 at 12:30
  • `char*` is very inefficient alone in most cases. See the famous [Shlemiel the painter algorithm](https://www.joelonsoftware.com/2001/12/11/back-to-basics/) – phuclv Jun 16 '21 at 12:33
  • Reminder: differentiate between `char`, a *single character* and `char *`, a pointer to a single character. Also, sometimes `char *` will point to an array of characters, and if you are lucky, a nul terminated sequence of characters, a.k.a. C-String. – Thomas Matthews Jun 16 '21 at 15:10

5 Answers5

6

C and C++ are different languages, no matter how similar they look and what common subset they have. Being different languages, they have methods that work only within that language. Mixing them is fine when you know what you are doing. As the other answer states, char arrays are more difficult to use than std::string, although they have their advantages. For a beginner, if you want to learn C++, learning std::string will save you quite a lot of debugging strange things happening in your code compared to using char*


The reason why you don't need typedef struct {} X is a prime specimen of C and C++ being different languages. You will not need to repeat struct X every time you use in C++, with or without typedef. I'd even say it's harmful, because void foo(struct X*) does something more than just void foo(X*). Moreover, struct in C++ is equivalent to class, the only difference is the default access specifier (struct has public as default, class has private).

Yksisarvinen
  • 18,008
  • 2
  • 24
  • 52
  • 2
    Also, the C standard library is available in C++. Quite a lot of C code will compile through a C++ compiler and will execute just fine. However, there different conventions and idioms in C and C++. That is why `malloc()` is not good C++ even though you are able to use it. `std::string` is preferred over [raw pointers](https://learn.microsoft.com/en-us/cpp/cpp/raw-pointers?view=msvc-160) because we can avoid explicit memory management. We can lean on the C++ standard library to do the memory management for us. Raw pointers are bad modern C++: use unique pointers or shared pointers. – Daniel Dearlove Jun 16 '21 at 12:32
3

zero terminated char * strings have been the source of an enormous number of bugs, crashes and security flaws over the years, usually because someone forgets to zero terminate them, or because they forget a 4 character string needs to be 5 characters long, or a number of other scenarios.

They CAN be used safely, but experience tells us we will make mistakes, and waste time and effort testing and checking and testing again, when we could just use a string class, that contains all the checks in one place, is tested in one place, and never needs to be worried about again. So why on earth wouldn't we?

Andy Newman
  • 1,178
  • 2
  • 8
  • 23
  • 1
    ...also using a `char*` as a class member rather than a `std::string` means you can't rely on any of the compiler generated constructors, assignment operator, or destructor. – Bathsheba Jun 16 '21 at 12:24
  • There's also the case of comparing two pointers to characters, instead of comparing their target contents. – Thomas Matthews Jun 16 '21 at 15:11
0

What if we should work with char in C++ project because of several reasons?

There is nothing stopping you :D

That said, the design of std::cin and std::string is the way it is, because working with char* and scanf is error prone and inefficient (and they were added to the C++ standard library to provide better ways).

There are reasons to work directly with char* in C++, but most of them are really bad reasons (a good reason would be to learn - for example).

utnapistim
  • 26,809
  • 3
  • 46
  • 82
0

The C++ compiler doesn't care if you mix C style code with C++ style code, it will produce some result.

Other humans care if you mix C style code with C++ style code, because it's really easy for it to do something subtly different from what you think it should.

C++ is not a safe language, where you simply can't do wrong things, nor is it a safer language, which will loudly tell you when you do wrong things. It is an unsafe language, where if you do things wrong, you might not notice right up until the worst possible moment.

Caleth
  • 52,200
  • 2
  • 44
  • 75
0

This is an opinion-based question (which I suppose is why it's been downvoted), so I'm going to wade in here with a dissenting opinion:

Why char and other C function should not be used in C++?

Well, it's partly because some people have rigid opinions on what programming should be, and they like to try to force these opinions on you. :-)

It's true that C has many unsafe aspects, particularly by modern standards. It's true that C++ has "better" or at least different ways of dealing with several things, including strings, I/O, and memory allocation.

But at the end of the day, programming languages are tools, and using them appropriately is always a balance between using them as designed, and getting your job done.

C++ was designed to be a superset of C. (These days it's not, of course, but the intent is still clearly there.) So there's nothing inherently wrong with using C features or idioms in a C++ program -- the whole point of Bjarne Stroustrup's exercise was always to allow you to.

If you choose to use a C feature in a C++ program, it might be an ignorant or a bad or a dangerous thing to do, or it might be expedient and decently appropriate thing to do. At the end of the day, it depends on whether it gets the job done, whether it's maintainable, and whether it's acceptable to any other people you may be sharing code or collaborating with.

For example, I code in both C and C++. And while I understand how cout and << are a "better" way of doing output than C's printf, I confess that I still use printf in C++ programs a lot of the time, because it's so much more convenient. Despite its notorious and insurmountable warts and problems, printf has always been one of my favorite parts of C, and I am loath to give it up.

I'm not saying you should use printf in C++, or that you should ignore all the various benefits of std::string, and new/delete, and the STL. "When in Rome, do as the Romans do" is a fine philosophy, and most of the time, you should use C++ idioms in C++. But if you have a good reason to fall back on a C idiom once in a while, I don't believe there's any shame in that, and I don't believe you should let anyone guilt-trip you into abandoning it just because they think it's "not proper".

[It will be interesting to see how violently this answer gets downvoted for its heretical advice. :-) ]

Steve Summit
  • 45,437
  • 7
  • 70
  • 103
  • 1
    Well, `cout` and `<<` aren't a "better" way of doing output. The design of iostreams is pretty much universally despised. Just a few of the major architectural issues with it: Violation of single responsibility because it blends formatting and I/O. Terrible performance. Abuse of operator overloading (`<<` and `>>` exist in the language as bit shift, and their precedence and associativity are correct for bit shift, not extraction/insertion). Lack of a consistent approach to error handling. Half-baked support for localization. – Ben Voigt Jun 16 '21 at 15:41
  • @BenVoigt That's why I put "better" in quotes. :-) I didn't realize other people disliked them so. Good to know. But an overloaded operator, though, that's a *feature*, right? So that an iostream can automatically and consistently handle new types in a way that `printf` and friends never will. – Steve Summit Jun 16 '21 at 15:47
  • Type-safe extensibility is a feature. That's not in any way unique to operator overloads. `std::less` is just as type-safe and just as extensible as `operator<` – Ben Voigt Jun 16 '21 at 15:58
  • And in fact, iostreams *don't* provide extensible insertion and extraction. By using operators, all parameters to the operation have to be stored as state on the stream, and the library pre-determined what state can be stored. radix, width, padding, precision? Yes. Pluralization, color, font size and attributes such as bold or italic, language-specific word order? No. You can define your own manipulators but there's no place for custom manipulators to store state. – Ben Voigt Jun 16 '21 at 16:04
  • @BenVoigt Okay, fair point about extensibility. (And, yes, it's the statefulness that I dislike the most.) – Steve Summit Jun 16 '21 at 16:04