Does the system() function belong to C or C++? - c++

#include <stdio.h>
#include <stdlib.h>
void main ()
{
system("dir");
}
I have read in many C++ books where system() is used to execute command line programs. But when I tried the same command in C, it worked perfectly. So my question is whether its a standard C or C++ function? Please be liberal as I am new to C programming.

As system function is declared in stdlib.h, it can be considered a C function. But in C++, stdlib.h is merged into the std namespace and is located in the cstdlib include in this form. So the correct answer is "both".

It is both C and C++.
system : http://en.cppreference.com/w/c/program/system
std::system: http://en.cppreference.com/w/cpp/utility/program/system

Both: it's defined by the standard C library, and the standard C++ library contains the C library.
In C++, you should include the C++ style header, <cstdlib>, and refer to it as std::system. Including C headers directly is deprecated.

It's both. C defines many functions. C++ defines many functions that are exactly the same as in C, some that are subtly different from how they are in C, and a lot of functions and classes that aren't part of C at all. Knowing that a function is part of standard C++ says nothing about whether it is part of standard C, and knowing that a function is part of standard C says little about whether it is part of standard C++.

Both c and cpp support the function system as they have support for the stdlib.h that contains the prototype of system() function.

Related

Standard C++ way of calling C standard library functions

I have a few questions about calling C standard library functions in C++:
If I want to call getline() which is declared in <stdio.h> is it always sufficient to just include <cstdio>? This works with the compiler I'm using and I see that it includes <stdio.h> in <cstdio> but I want to know if the standard guarantees this.
Are all C standard library functions guaranteed to be available in C++? With the getline() example from above I noticed that on cppreference under <cstdio> it doesn't list getline().
For C standard library functions and types that are made available in the std:: namespace like FILE or malloc() are they any problems with accessing them through the global namespace or is it just more idiomatic to access them as std::FILE or std::malloc()?
You should always include what the documentation tells you to. (C++ standard library implementations will often be written such that functions are reachable via other includes but of course relying on that means your code is not portable.) Note that there is no standard getline function in C. But there is one in C++:
std::getline()
is defined in header <string>. The C++ standard doesn't guarantee that, in general, C functions are available at global scope or are even part of the C++ standard library. The two languages began their divergence many years ago and so the idea that C++ is in a sense a superset of C - libraries included - is a myth.
Reference: https://en.cppreference.com/w/cpp/string/basic_string/getline
In relation to #3:
The .h libraries must place all its names in the global namespace and may also place them in the std:: namespace.
The c begining version must place all its names in the std:: namespace and may also place them in the global namespace.
It should be easy to link any C library with C++ in general, not just the standard headers.
Note that you may have to trawl through man to work out what version of what unix the method was introduced or if it is a specific extension, and decide for yourself if that historical startpoint is acceptable to you. But this is true if you wrote a C program instead of C++.
The C++ alias headers include most, but not all of the functionality from the C headers, but occasionally you may find the only way to get a function is to include the C header directly. On the other hand you need to ask yourself why they chose not to include that method, usually because it is deprecated, dangerous, or non-standard.
So the way it works, is that C functions, including C library functions are introduced with the extern "C" keyword.
When you #include C header files they will generally contain some code such as:
/* C++ needs to know that types and declarations are C, not C++. */
#ifdef __cplusplus
# define __BEGIN_DECLS extern "C" {
# define __END_DECLS }
#else
# define __BEGIN_DECLS
# define __END_DECLS
#endif
__BEGIN_DECLS
... which introduces a section of C interface functions.
If you needed to include a really old C library that did not do this, then you could easily add extern "C" around the #include:
extern "C" {
#include "ancientinterface.h"
};
You can also write your own methods that are "C" interface compatible.

Using Linux API headers made for C in C++

Let's consider this piece of code:
#include <iostream>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
using namespace std;
int main(void) {
char hi[14] = "Hello world!\n";
if (write(1, hi, strlen(hi)) < 0) {
perror("write");
}
cout << "Done" << endl;
return 0;
}
Here, I'm mixing all kinds of C and C++ code to make something ... work. I'm writing on stdout directly and using some C headers like string.h and stdio.h. Is this considered bad? Could undefined behavior arise? Is C code "compatible" with C++ so I just include it and use it?
The program works just fine.
Hello world!
Done
Is this considered bad?
Some programmers consider it bad style to use C library functions when there are superior C++ library functions available. However, there are cases where it is better to use the C library functions.
Could undefined behavior arise?
Probably not. The C++ standard library incorporates almost the entire C standard library (with a few minor changes), so calls to C library functions from C++ are well-defined. As for functions such as write, their behaviour is defined by POSIX.
Is C code "compatible" with C++ so I just include it and use it?
For standard C library headers, yes. For implementation headers, typically yes; they are usually designed so that they can be validly included into C++ programs. For other headers... maybe. Not all C code is valid C++, but the degree of compatibility is high.
C++ forked from C a long time so, and the two languages have evolved independently.
The C++ standard describes deliberate incompatibilities that were introduced to C++ relative to the C standard from which it derived: http://eel.is/c++draft/diff.iso.
The mistake people make is in thinking this is a complete list of differences. C itself has evolved, and while parts of C99 were incorporated in recent versions of C++ not all have (VLAs, flexible array members, compound literals, ...).
C11 made the gap much wider, from small things like the removal of gets (still included in C++17) to things like bounds checking interfaces, threading support, and c-variants of c++ features like _the Static_assert keyword.
So for the most part you can get away with old-C-ish code in a C++ program, a few small changes that will cause compiler errors, a couple that might not, and nearly 20 years of C advances that you only have partial accesso to.
If you really want to write C-like code, consider writing C code and taking advantage of the full set of language improvements available in that language. The result will be much higher quality code than the rubbish you'll knock up restricting yourself to C++'s subset of C.
Gala,
Yes this is fine. C++ is a superset of C, you can blend the two with ease. In fact, many older programmers (like me) write C++ with a C style. In this style, printf, strcpy, no templates, RogueWave rather than stl, etc are used with C++ classes. Sometimes this is termed 'C with classes'.
--Matt

Legal to forward declare C standard library entities but not C++ standard library entities?

Can entities in the C standard library legally be forward declared in C++?
I just asked this same question but for C and so far the answer seems to be yes.
Forward declare entities in C standard library?
I know that entities in the C++ standard library cannot be forward declared for the reasons given in the linked question above. Before thinking of this question I would have said that the C standard library is part of the C++ standard library and therefore entities in the C standard library cannot be forward declared in C++.
Now I'm not sure. It would be surprising if the C++ standard mandates something about the C standard library that the C standard does not.
My understanding is that in practice, implementations of C++ tend to come with an implementation of C and the same header files and libraries are used for each (but optionally rebranded as for C++). So in practice, forward declarations of entities in the C standard library will likely compile just fine in C++. Still, I'm curious about what the C++ standard mandates.
The problem is that C++ and C are not compatible at the object level... For example it's different to write:
double atof(const char *);
and
extern "C" {
double atof(const char *);
}

Should I include <xxxx.h> or <cxxxx> in C++ programs?

What should I include in C++ programs, stdio.h or cstdio? and Why?
Why two header files which provide the same functionality?
What does the standard say regarding this?
How should I go about including other such headers, Is there a base rule that I should follow?
Consider the following programs:
Sample 1:
#include<stdio.h>
int main()
{
printf("Hello World");
return 0;
}
Sample 2:
#include<cstdio>
int main()
{
printf("Hello World");
return 0;
}
Both work as expected. So which usage is more appropriate?
The answer is: Neither! Surprised? Read on.
The C++ Standard library provides all standard C headers for compatibility reason, while C++ as a language also provides all the equivalent headers. As a convention,
No C++ standard library headers(apart from ones include for C compatibility) have any file extensions, and
All C++ equivalent of C headers begin with cxxxxx.
The C++ Standard mentions this under Annex D (normative) Compatibility features:
§2 mentions the important distinguishing point. This rule applied to the examples above means:
Including cstdio imports the symbol names in the std namespace and possibly in the Global namespace.
Including stdio.h imports the symbol names in the Global namespace and possibly in the std namespace.
Let us apply this rule to our sample codes and measure the pros and cons:
Sample 1:
This brings all the symbols from stdio.h in the global namespace. Advantage is that you can use the symbols without any qualification since they are imported in the global namespace. Downside is that you end up polluting the global namespace with many symbol names that you will probably never use. This might lead to symbol name collision. In C++ always consider the global namespace as a minefield and avoid it as much as possible.
Sample 2:
This is a very bad practice because there is no guarantee that the implementation will put the symbols in global namespace, the standard simply does not demand to do so. We are simply relying on the behavior of one particular compiler implementation. We cannot and should not assume that all compilers will do so. So strictly speaking the program is not standard approved and this usage is not portable across all implementations.
So what is the correct usage?
The correct usage is to use cstdio and fully qualify the symbol names or else bring them in scope with using declarations. This guarantees all symbols we use are present in std namespace and we are not polluting the global namespace. Example of correct usage:
Sample 3:
#include<cstdio>
using std::printf;
int main()
{
printf("Hello World");
return 0;
}
Note that the directive using namespace std;, especially in a header, is not a good option and you should always use using declarations.
Note that we consider stdio.h vs. cstdio here just a sample use case, in practice it applies to all most cxxxx and xxxx.h headers, except a few like <math.h> and <cmath>.
Since this post is a bit old I wanted to share the following:
Looking at code:
Using X.h // Compatible with C language standard
---------------
#include <X.h>
int main() {
// Invoke X's corresponding function
return 0;
}
Using X // Not compatible with C language standard
--------------
#include <X>
int main() {
// Invoke X's corresponding function
return 0;
}
They both compile and execute ok!
Which one is better in C++?
Regarding C++11's and C++17's specification:
C.5.1 (section from C++17 document)
Modifications to headers [diff.mods.to.headers]
For compatibility with the C standard library, the C++ standard library provides the C headers enumerated in D.5, but their use is
deprecated in C++.
There are no C++ headers for the C headers <stdatomic.h>, <stdnoreturn.h>, and <threads.h>, nor are the C headers themselves
part of C++.
The C++ headers <ccomplex> (D.4.1) and <ctgmath> (D.4.4), as well as their corresponding C headers <complex.h> and <tgmath.h>, do not
contain any of the content from the C standard library and instead
merely include other headers from the C++ standard library.
D.5
C standard library headers [depr.c.headers]
For compatibility with the C standard library, the C++ standard library provides the C headers shown in Table 141.
Both C++11 and C++17 standard specifications documents state the use of <X.h> remains for compatibility with the C standard, although their use is regarded as deprecated.
Regarding C++ 20 standard proposal
They are reviewing "undeprecating" the use of the C library headers in C++20. <X.h> appear highlighted in green. C++11 and C++17 deprecation, as of now, is stated as a "weak recommendation" and a "tweak" for keeping the "C standard library headers (c.headers)" is displayed below:
"The basic C library headers are an essential compatibility feature, and not going anywhere anytime soon." (from C++ 20 review document)
D.5 C standard
library headers [depr.c.headers]
Weak recommendation: In addition to the above, also remove the
corresponding C headers from the C++ standard, much as we have no
corresponding <stdatomic.h>, <stdnoreturn.h>, or <threads.h>, headers.
As above, but with the following tweaks:
20.5.5.2.1 C standard library headers [c.headers]
For compatibility with the C standard library, the C++ standard
library provides the C headers shown in Table 141. Table 141 — C
headers
<assert.h> <inttypes.h> <signal.h> <stdio.h> <wchar.h>
<complex.h> <iso646.h> <stdalign.h> <stdlib.h> <wctype.h>
<ctype.h> <limits.h> <stdarg.h> <string.h>
<errno.h> <locale.h> <stdbool.h> <tgmath.h>
<fenv.h> <math.h> <stddef.h> <time.h>
<float.h> <setjmp.h> <stdint.h> <uchar.h>
The header <complex.h>
behaves as if it simply includes the header <complex>.
The header <tgmath.h> behaves as if it simply includes the headers <complex> and <cmath>.
Bjarne Stroustrup recommends maximising inter-operability between
the C and C++ languages, by reducing incompatibilities as much as
possible. Others argue otherwise, as it complicates things.
So, it seems <X.h> aren't going anywhere. Ultimately, you can use both. Personally, I would make the decision of which one I would use boil down to having your code backwards compatible with C code or not.

stdio.h not standard in C++?

I know most compilers allow both:
#include <stdio.h>
and
#include <cstdio>
But someone argued that <stdio.h> is not actually C++ standard. Is that true?
stdio.h is standard, but deprecated. Always prefer cstdio in C++.
[n3290: C.3.1/1]: For compatibility with the Standard C library, the
C++ standard library provides the 18 C headers (D.5), but their use is
deprecated in C++.
[n3290: D.5/3]: [ Example: The header <cstdlib> assuredly
provides its declarations and definitions within the namespace std. It
may also provide these names within the global namespace. The header
<stdlib.h> assuredly provides the same declarations and definitions
within the global namespace, much as in the C Standard. It may also
provide these names within the namespace std. —end example ]
It's not true, because C++ main goal is backward compatibility with C. The only difference is that for
#include <cstdio>
all functions are in std namespace
The C standard headers are included in the C++ standard library for compatibility.
The difference is that identifiers in corresponding C++ headers must (also) be in std namespace, whereas identifiers in C headers must (also) be available in global namespace.
In addition, the <c...> headers add overloads for functions like abs, pow etc.
Also, C++ headers replace some C classification/comparison macros with overloaded functions.
The C++ standard library explicitly contains the C standard library, so is an entirely legitimate part of C++. And if you are talking about using #include <stdio.h> in C++ code, then you shouldn't do that, cause that's C syntax, in C++ code, you should use always cstdio