Sinf - Does it exist in C++? - c++

I was curious to know whether or not the sinf function existed in C++ through including math.h.
When viewing my auto-completion in Qt Creator, it doesn't appear to pop up. It makes me wonder if, for some reason, it was taken out. A Google search doesn't seem to pop up with many references either; most of them are in reference to straight C.
So, can this be confirmed?

It depends on which version of the standard your implementation supports.
The sinf function did not exist in the 1990 ISO C standard (nor did sind). The only sin function was sin, which takes a double argument and returns a double result. (The "Future Library Directions" section, 7.13, does say that math functions with names suffixed with f or l are reserved.)
The sinf and sind functions were added in the 1999 ISO C standard (C99).
The 2003 edition of the ISO C++ standard says, in section 17.4.1.2 [lib.headers]:
Except as noted in clauses 18 through 27, the contents of each header
cname shall be the same as that of the corresponding header name.h, as
specified in ISO/IEC 9899:1990 Programming Languages C (Clause 7), or
ISO/IEC:1990 Programming Languages—C AMENDMENT 1: C Integrity, (Clause
7), as appropriate, as if by inclusion.
The 2011 ISO C++ standard (at least the N3290 draft) includes the following as normative references:
ISO/IEC 9899:1999, Programming languages — C
ISO/IEC 9899:1999/Cor.1:2001(E), Programming languages — C, Technical Corrigendum 1
ISO/IEC 9899:1999/Cor.2:2004(E), Programming languages — C, Technical Corrigendum 2
ISO/IEC 9899:1999/Cor.3:2007(E), Programming languages — C, Technical Corrigendum 3
So a C++ implementation that conforms to a standard earlier that C++11 needn't provide sinf. It's not clear whether it's permitted to do so, but since all standard prior to C++11 are officially obsolete, it's probably a moot question.
It's probably common for pre-C++11 implementations to provide sinf() and friends as a (possibly non-conforming) extension.
Practically, you can always just call sin(); in most cases the argument and result will be implicitly converted from float to double and from double to float. There might (or might not) be some loss of efficiency.

All C functions exist in C++, unless their header files take the explicit step of checking whether it's a C++ compiler and hiding the definition in that case.
So yes, you may use sinf from C++ code just like you would from C. In fact, you can (with a few very narrow exceptions) write C90 code and pass it through g++, calling it C++.
EDIT: sinf, at least on my machine, is not exposed by math.h unless one of the following is #defineed before including that header:
_BSD_SOURCE || _SVID_SOURCE || _XOPEN_SOURCE >= 600
|| _ISOC99_SOURCE || _POSIX_C_SOURCE >= 200112L
So in C++ code you might need to set one of those preprocessor defines in order to get the prototype.

Related

Where in the C++11 standard is std::fmodf stated?

According to the cppref page, std::fmodf was added to cmath in C++11. How is this possible though, because wouldn't this mean that cmath would break compatability with math.h previous to C++11? I'm unable to find any references that say std::fmodf was added in C++11 and was wondering where this is stated.
Thank you
Where in the C++11 standard is std::fmodf stated?
It wasn't mentioned directly (although it probably should have been mentioned either in the list of functions, or explicitly omitted). The change that causes std::fmodf to exist is here (quote from draft N3337):
The following referenced documents are indispensable for the application of this document. For dated references, only the edition cited applies. For undated references, the latest edition of the referenced document (including any amendments) applies.
...
ISO/IEC 9899:1999, Programming languages — C
...
Through the following rule:
[c.math]
The contents of these headers are the same as the Standard C library headers <math.h> and <stdlib.h> respectively, with the following changes: ...
C99 added fmodf. It was inherited to C++ when C++11 started referring to the standard library of C99 instead of C89.
Note, the "following changes" do not list omission of fmodf.
Why isn't fmodf listed in the list of functions (26.8/3 and 26.8/9)? It was added to the list in the C++17 standard.
This appears to have been an editorial mistake. It seems to have been fixed in C++17 by P0175 which proposes:
In this editorial paper we propose to add to the working draft the complete synopses of the C library headers that are included in C++ by reference to the C standard (see Table 15). These synopses will replace the various tables captioned “Header synopsis”.
Sidenote: std::fmodf is fairly useless in C++, since you can simply use std::fmod instead, and that has been around since C++98.

How is `void main` invalid, when it compiles just fine?

I find about int main definition, but not of void main in introduction of c++ programming language. I tried reading all the articles written in introduction of c++ programming language.
void main has never been valid in either C or C++.
C++11 §3.6.1/2:
” An implementation shall not predefine the main function. This function shall not be overloaded. It shall have a return type of type int, but otherwise its type is implementation-defined. All implementations shall allow both of the following definitions of main:
int main() { /* ... */ }
and
int main(int argc, char* argv[]) { /* ... */ }
…
C++11 §3.6.1/5:
” A return statement in main has the effect of leaving the main function (destroying any objects with automatic storage duration) and calling std::exit with the return value as the argument. If control reaches the end of main without encountering a return statement, the effect is that of executing
return 0;
The value 0 is one value that indicates process success. The value EXIT_SUCCESS from <stdlib.h> may be 0 or some other value. The value EXIT_FAILURE indicates process failure.
Using void main is not standard, although there is some history regarding why some compilers allow it.
The following is from a 2008 post on programingforums.org:
In 1971, Denis Ritchie (who was working alongside Ken Thomson
developing Unix) produced a "new B" by add support for the character
type, and modified the early B compilers to output machine code. In
1972, "new B" was renamed to C. A preprocessor was added in 1973 or so
and another programmer in the team produced the "portable I/O
package", which was later renamed to the C "standard I/O routines".
Hence the first version of C was born: it supported only char,
integer, and pointer types. There was no void keyword.
Denis Ritchie and Brian Kernighan worked together to enhance C. Later
versions of C introduced more of the standard library, such as
malloc() - which originally returned pointer to char, as there was no
void pointer. Hence it was always necessary in early versions of C to
cast the return from malloc(). Support for floating point was also
added. This became what is known as Kernighan and Ritchie (K&R) C.
In the early 1980s, a decision was made to ratify C as a standard,
leading to the development of the first ANSI Standard in 1989 (then
ratified as an ISO standard in 1990). In the committee process leading
to the standard, a number of changes were made: in particular the void
keyword was introduced, the form of function prototypes was changed.
During the standardisation process, several commercial compilers were
developed. Some of these supported void main() as a work-around for
compiler diagnostics about falling off the end of main(). They lobbied
unsuccessfully for this to be supported by the C standard, but that
was not accepted as other vendors considered it added no significant
or useful new functionality. Later, in the early 1990s, when "standard
compliance" became a marketing tool, they unleashed lawyers on the
standard and found the wording loop-hole that - they then claimed -
allows void main() to be considered as standard.
During the C standardisation process, Bjarne Stroustrup started work
on the development of C++, and published the ARM (Annotated Reference
Manual) with Margaret Ellis in 1990. Since that happened in parallel
with the minor flurry associated with void main(), that feature was
never part of C++. The ARM was the basis for development of the C++
standard, which was finally ratified by ANSI in 1998 and ISO in 1999.
During development of the 1999 C standard, there was some discussion
about void main(), but it never gained traction - the push in favour
was political, and overall consensus was apparently that it offered
little technical benefit. Hence the 1999 C standard explicitly
disallows it.

What is the Relationship Between the C and C++ Standards?

I was writing this answer and I quoted from http://en.cppreference.com/w/cpp/string/byte/tolower#Parameters
Is not representable as unsigned char and does not equal EOF, the behavior is undefined
When I went to inspect the edit that had added this phrase I found that the author's comment:
Can't use negative signed chars with any ctype.h function per C99 7.4/1
The author is citing from the C99 standard in C++ documentation. Is that valid? I couldn't find anything on the definition of this function in the C++ standard, so I must assume that it is valid.
But this concerns me for 2 reasons:
How would I know what version of the C standard the C++ standard depends upon?
There are lists of the discrepancies between C and C++ everywhere. If I'm looking at the C standard with reference to C++ how could I possibly know whether the area I'm looking at has been overridden?
For the first question:
The C++ standard explicitly lists the C standard(s) on which it depends in its Normative references section. For C++14, [intro.refs] 1.2/1 happens to list C 99:
ISO/IEC 9899:1999, Programming languages — C
ISO/IEC 9899:1999/Cor.1:2001(E), Programming languages — C, Technical Corrigendum 1
ISO/IEC 9899:1999/Cor.2:2004(E), Programming languages — C, Technical Corrigendum 2
ISO/IEC 9899:1999/Cor.3:2007(E), Programming languages — C, Technical Corrigendum 3
For the second question:
The C++ standard does not implicitly incorporate any parts of the C standard; all references to the C standard are explicit. A good source of information on where C++ deviates from C is Annex C, "Compatibility" of the C++ standard, particularly C.1 [diff.iso].
Additionally, references to the C standard library are scattered throughout the description of the C++ standard library (chapters 17–30 in C++14). Of particular interest can be:
17.2 [library.c], which describes the basic inclusion of the C standard library
Chapter 18 [language.support], which describes many of the <c:::> headers of the C++ standard library (those which offer the C standard library functionality).
How would I know what version of the C standard the C++ standard depends upon?
In C++ 14, it's ISO/IEC 9899:1999 (plus three corrigendums, so C99 in essence) as stated in 1.2 [intro.refs] in N4140. In C++98, it was C90, in C++17, it probably will be C11, but the C++ standard will always make that explicit.
If I'm looking at the C standard with reference to C++ how could I possibly know whether the area I'm looking at has been overridden?
You look in the C++ standard, it either explicitly imports the C definitions minus restrict or any C behavior it wants or makes explicit modifications.
Usually, reading good documentation instead of the standard itself will serve you just fine.
To address your initial question:
The author is citing from the C99 standard in C++ documentation. Is that valid?
Yes, because
1
Tables 74 [contains std::tolower, me], 75, 76, 77, 78, and 79 describe headers <cctype>, <cwctype>, <cstring>, <cwchar>, <cstdlib>
(character conversions), and <cuchar>, respectively.
2
The contents of these headers shall be the same as the Standard C Library headers <ctype.h>, <wctype.h>,
<string.h>, <wchar.h>, and <stdlib.h> and the C Unicode TR header <uchar.h>, respectively, with the
following modifications [none of those apply to std::tolower, me]:
21.8 [c.strings] in N4140
The edit is correct and this particular text has been in the standard since C90.
From C90 4.3
The header declares several functions useful for testing
and mapping characters. In all cases the argument is an int , the
value of which shall be representable as an unsigned char or shall
equal the value of the macro EOF . If the argument has any other
value, the behavior is undefined.
From C11 7.4/1
The header declares several functions useful for classifying
and mapping characters. In all cases the argument is an int, the
value of which shall be representable as an unsigned char or shall
equal the value of the macro EOF. If the argument has any other value,
the behavior is undefined.
Identical text; C has always been like this. So it doesn't matter which C version your particular C++ version uses, because all C versions are equivalent.

ISO C++ and the infamous underscore [duplicate]

This MSDN article states that getcwd() has been deprecated and that the ISO C++ compatible _getcwd should be used instead, which raises the question: what makes getcwd() not ISO-compliant?
There is a good discussion about that. P.J. Plauger answers to this
I'm the guy who insisted back in 1983 that the space of
names available to a C program be partitioned into:
a) those defined by the implementation for the benefit of the programmer (such as printf)
b) those reserved to the programmer (such as foo)
c) those reserved to the implementation (such as _unlink)
We knew even then that "the implementation" was too monolithic --
often more than one source supplies bits of the implementation --
but that was the best we could do at the time. Standard C++
has introduced namespaces to help, but they have achieved only
a fraction of their stated goals. (That's what happens when you
standardize a paper tiger.)
In this particular case, Posix supplies a list of category (a) names
(such as unlink) that you should get defined when and only when you
include certain headers. Since the C Standard stole its headers from
Unix, which is the same source as for Posix, some of those headers
overlap historically. Nevertheless, compiler warnings should have
some way of taking into account whether the supported environment
is "pure" Standard C++ (a Platonic ideal) or a mixed C/C++/Posix
environment. The current attempt by Microsoft to help us poor
programmers fails to take that into account. It insists on treating
unlink as a category (b) name, which is myopic.
Well, GCC will not declare POSIX names in strict C mode, at least (though, it still does in C++ mode):
#include <stdio.h>
int main() {
&fdopen;
return 0;
}
Output using -std=c99
test.c: In function 'main':
test.c:4: error: 'fdopen' undeclared (first use in this function)
You will have to tell it explicitly that you are operating in a mixed C/Posix by using feature test macros or not passing any specific standard. It will then default to gnu89 which assumes a mixed environment (man feature_test_macros). Apparently, MSVC does not have that possibility.
Functions not specified in the standard are supposed to be prefixed by an underscore as an indication that they're vendor-specific extensions or adhere to a non-ISO standard. Thus the "compliance" here was for Microsoft to add an underscore to the name of this specific function since it's not part of the ISO standard.
As others have already pointed out, getcwd is not included in ISO C++, but is part of POSIX/IEEE Std 1003.1.
Microsoft has decided to include some of the most commonly used POSIX functions in their C standard library (but prefix these functions with an underscore to essentially discourage their usage).
For the record, getcwd() wasn't deprecated by ISO. It was "deprecated" by Microsoft. Microsoft rewrote many C functions -- often with a little better security in mind (say, string functions that also take a max_length parameter). They then had their compiler spit out these warnings, which I consider bogus because no standards group deprecated any of the functions declared deprecated.
To add on to Dan Olson's post: See ANSI C Compliance page on MSDN
The names of Microsoft-specific functions and global variables begin with a single underscore. These names can be overridden only locally, within the scope of your code. For example, when you include Microsoft run-time header files, you can still locally override the Microsoft-specific function named _open by declaring a local variable of the same name. However, you cannot use this name for your own global function or global variable.
As far as I'm aware getcwd() has never been part of ISO Standard C++. _getcwd() definitely isn't, as standard names will not begin with an underscore.
In fact, the MSDN article links to a man page that says it is declared in direct.h, which is not a Standard C++ header file. The article seems bogus to me.
The MSDN article is somewhat confusing in what a normal person would conclude from just a quick reading (if they don't read it with a very careful lawyer eye).
What the MSDN article says is: getcwd() is not compliant with the ISO C++ standard. To comply with that ISO C++ standard for naming of functions (which is what getcwd violates), Microsoft properly put an _ on the front of the function, so the same function becomes _getcwd(). That is the ISO C++ compliant way of naming the function because getcwd() and _getcwd() are not an ISO C++ standard function, but are a Microsoft (vendor) specific, or implementation specific function.
The article does not indicate what a C++ ISO standard call to get the working directory would be... though thats what folks tend to read at a quick glance.

Why is getcwd() not ISO C++ compliant?

This MSDN article states that getcwd() has been deprecated and that the ISO C++ compatible _getcwd should be used instead, which raises the question: what makes getcwd() not ISO-compliant?
There is a good discussion about that. P.J. Plauger answers to this
I'm the guy who insisted back in 1983 that the space of
names available to a C program be partitioned into:
a) those defined by the implementation for the benefit of the programmer (such as printf)
b) those reserved to the programmer (such as foo)
c) those reserved to the implementation (such as _unlink)
We knew even then that "the implementation" was too monolithic --
often more than one source supplies bits of the implementation --
but that was the best we could do at the time. Standard C++
has introduced namespaces to help, but they have achieved only
a fraction of their stated goals. (That's what happens when you
standardize a paper tiger.)
In this particular case, Posix supplies a list of category (a) names
(such as unlink) that you should get defined when and only when you
include certain headers. Since the C Standard stole its headers from
Unix, which is the same source as for Posix, some of those headers
overlap historically. Nevertheless, compiler warnings should have
some way of taking into account whether the supported environment
is "pure" Standard C++ (a Platonic ideal) or a mixed C/C++/Posix
environment. The current attempt by Microsoft to help us poor
programmers fails to take that into account. It insists on treating
unlink as a category (b) name, which is myopic.
Well, GCC will not declare POSIX names in strict C mode, at least (though, it still does in C++ mode):
#include <stdio.h>
int main() {
&fdopen;
return 0;
}
Output using -std=c99
test.c: In function 'main':
test.c:4: error: 'fdopen' undeclared (first use in this function)
You will have to tell it explicitly that you are operating in a mixed C/Posix by using feature test macros or not passing any specific standard. It will then default to gnu89 which assumes a mixed environment (man feature_test_macros). Apparently, MSVC does not have that possibility.
Functions not specified in the standard are supposed to be prefixed by an underscore as an indication that they're vendor-specific extensions or adhere to a non-ISO standard. Thus the "compliance" here was for Microsoft to add an underscore to the name of this specific function since it's not part of the ISO standard.
As others have already pointed out, getcwd is not included in ISO C++, but is part of POSIX/IEEE Std 1003.1.
Microsoft has decided to include some of the most commonly used POSIX functions in their C standard library (but prefix these functions with an underscore to essentially discourage their usage).
For the record, getcwd() wasn't deprecated by ISO. It was "deprecated" by Microsoft. Microsoft rewrote many C functions -- often with a little better security in mind (say, string functions that also take a max_length parameter). They then had their compiler spit out these warnings, which I consider bogus because no standards group deprecated any of the functions declared deprecated.
To add on to Dan Olson's post: See ANSI C Compliance page on MSDN
The names of Microsoft-specific functions and global variables begin with a single underscore. These names can be overridden only locally, within the scope of your code. For example, when you include Microsoft run-time header files, you can still locally override the Microsoft-specific function named _open by declaring a local variable of the same name. However, you cannot use this name for your own global function or global variable.
As far as I'm aware getcwd() has never been part of ISO Standard C++. _getcwd() definitely isn't, as standard names will not begin with an underscore.
In fact, the MSDN article links to a man page that says it is declared in direct.h, which is not a Standard C++ header file. The article seems bogus to me.
The MSDN article is somewhat confusing in what a normal person would conclude from just a quick reading (if they don't read it with a very careful lawyer eye).
What the MSDN article says is: getcwd() is not compliant with the ISO C++ standard. To comply with that ISO C++ standard for naming of functions (which is what getcwd violates), Microsoft properly put an _ on the front of the function, so the same function becomes _getcwd(). That is the ISO C++ compliant way of naming the function because getcwd() and _getcwd() are not an ISO C++ standard function, but are a Microsoft (vendor) specific, or implementation specific function.
The article does not indicate what a C++ ISO standard call to get the working directory would be... though thats what folks tend to read at a quick glance.