Ensure use of custom types - c++

Considering this answer for the benefit of typedefs on basic types and why they are used, is there any way to ensure that in your project you did not use a basic type and used the typedef counterparts?

If you really, absolutely want to ban native types but allow typedefs, I guess you can always do something like:
#include <stdint.h>
#define int please_use_stdint_typedefs_rather_than_native_types
int main()
{
int32_t good; // Good typedef.
int evil; // Evil native type.
}
$ gcc -c int_forbidden.c
int_forbidden.c: In function ‘main’:
int_forbidden.c:8: error: ‘please_use_stdint_typedefs_rather_than_native_types’ undeclared (first use in this function)
int_forbidden.c:8: error: (Each undeclared identifier is reported only once
int_forbidden.c:8: error: for each function it appears in.)
int_forbidden.c:8: error: expected ‘;’ before ‘evil’
That said, I don't think outright banning native types is a good idea in the general case.

You can make these typedefs Strong Typedefs as proposed in this boost library : http://www.boost.org/doc/libs/1_40_0/boost/strong_typedef.hpp

Considering a typedef is just a synonym for a type and does not actually create a new type, I don't think there would be any reliable way to ensure this. You could write a script to run through the code and look for occurrences of primitive types vs. the expected typedef counterpart.

Related

C++/ name conflict: how to exclude a previously defined function

I want to write log2() function for a new datatype that I defined myself Array. So it will look like this
#include <iostream>
#include <cmath>
Array log2(Array& A)
{
Array C=A;
for (int i=0; i<A.size(); i++)
C[i]=log2(A[i]);
return C;
}
despite other functions like sin, cos, etc, this one (log2) is not declared under std namespace. so even using the following
std::log2(A[i])
the compiler does not resolve that inside log2 is suppoed to be the built-in c function. I persist to use the same name (log2) for simplicity of the code.
This is the error message
error: invalid initialization of reference of type 'Array&' from expression of type 'double'
SOLVED: It worked when I switched to -std::C++ 11.
std::log2 was introduced in C++11. Make sure you have a C++11 compliant compiler (e.g. gcc4.8 or later, compile with -std=c++11), and use std::log2 inside your function.
If you don't use std::log2, then the compiler cannot find the standard function (as you are not using namespace std;) and tries to use yours, which of course is not defined for doubles, and you get an error.
My personal opinion is that you should try to avoid naming your function the same as a standard one, due to headaches that can later appear.
As far as I know, the built-in function log2 is not declared in namespace std.
You should use the following code to call the standard log2 function:
log2(A[i]);
I hope my answer helped.

Assigning an enum a max value via numeric_limits?

I'm having trouble assigning an element in an enuma max value. First:
protected:
enum {DEFAULT_PADDING=std::numeric_limits<enum>::max()};
Results in:
./basecode.h:30:51: error: expected identifier or '{'
enum {DEFAULT_PADDING=std::numeric_limits<enum>::max()};
^
./basecode.h:30:59: error: expected a type
enum {DEFAULT_PADDING=std::numeric_limits<enum>::max()};
(and a couple of others)
Second, switching to:
protected:
enum {DEFAULT_PADDING=std::numeric_limits<unsigned int>::max()};
Results in:
./basecode.h:30:27: error: expression is not an integral constant expression
enum {DEFAULT_PADDING=std::numeric_limits<unsigned int>::max()};
How do I have numeric_limits give me a value that I can use at compile time for an enum?
The library is older, so it supports a lot of older compilers and IDEs. I need something that is at least C++03 and preferably C++98.
And standard caveats apply: this is a simple make based project. It does not use Autotools, it does not use Cmake, it does not use Boost, etc.
In C++03, std::numeric_limits<T>::max() was simply static. In C++11, it became static constexpr. You need the latter in order to be used in an integral constant expression, so simply compiling with -std=c++11 will do.
If you can't use C++11, you can just use UINT_MAX.

Function pointer declaration works in C but not in C++

So i am currently importing a small C library into a new empty C++ project, but it simply won't compile. It works just fine compiling it with C, but it simply doesn't with C++. The only thing i am doing is including the header.
It seems to be a syntax fault, but it could be someting else. This is the only thing the compiler nags about:
error: expected unqualified-id before 'export'
bool (*export)(struct wld_exporter * exporter, struct wld_buffer * buffer, uint32_t type, union wld_object * object);
error: expected ')' before 'export'
Since i thought it was a syntax issue, i just didn't know what to do and tried stupid things like moving the asterix after export instead of prior hoping that it would work, but it obviously didn't.
I have no idea why the compiler can't recognize that it's supposed to be a function pointer, i have done function pointers c-style in c++ before without any issues.
I am using gcc and C++11 if that makes any difference.
export is a keyword in C++, you can't use it as an identifier.
List of keywords here: C++ keywords
export is a keyword in C++. You'll have to choose a different name.

Error checking through Macro

I want to compile a time error checking as mentioned below . But I am not able to find out how to use it inside main()?
#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
#define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int:-!!(e); }))
int main(){
BUILD_BUG_ON_NULL(12);
}
Below is the mentioned error
1--error C2332: 'struct' : missing tag name
2--error C2143: syntax error : missing ')' before '{'
3--error C2027: use of undefined type 'main::<unnamed-tag>'
4--error C2143: syntax error : missing ';' before '{'
5--error C2059: syntax error : ')'
Can anyone please let me know what I am doing wrong?
EDIT: the question was originally tagged as C++, but now as just C.
I'm not going to chase further fundamental changes of the question.
Original answer for the C++ tagged question:
This source code:
#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
#define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int:-!!(e); }))
int main(){
BUILD_BUG_ON_NULL(0);
}
compiled with g++ 4.7.1., produced
foo.cpp: In function 'int main()':
foo.cpp:4:1: error: types may not be defined in 'sizeof' expressions
foo.cpp:4:21: warning: statement has no effect [-Wunused-value]
Which says directly what’s wrong.
So it is a good idea to compile with different compilers.
Possibly you’re looking for compile time assertions.
With C++11 you can use static_assert, e.g. via a macro such as
#define STATIC_ASSERT( e ) static_assert( e, #e )
In C++03 you could implement it as a valid/invalid typedef, because a typedef can be repeated in the same translation unit, and can be used in a class definition:
#define STATIC_ASSERT( e ) typedef char staticAssert_shouldBeTrue[e? 1 : -1]
One problem with that was that g++ had/has a compiler bug, where a repeated typedef is not always accepted as it should be, necessitating generation of a locally unique name for each one, e.g. by using __LINE__.
But you can always just use the definition in the Boost library, since Boost supports most extant compilers with special-casing for each one as necessary.
First the macros BUILD_BUG_ON_ZERO and BUILD_BUG_ON_NULL trigger a compilation error if their argument is different than 0.
If the macro argument is 0, they will not trigger any compilation error but yield a 0 for BUILD_BUG_ON_ZERO and a (void *) 0 for BUILD_BUG_ON_NULL
These macros comes from the Linux kernel which is written in C and they are only working for C programs.
In C++ these macros are not working. The reason is in C++ you cannot declare a structure in a sizeof expression.
You don't mention in your question if you are compiling your program in C or in C++, but I strongly suspect you are compiling it in C++. So don't use these macros in C++.
Compiling with gcc -std=c99 -pedantic-errors, I get
screwed.c: In function ‘main’:
screwed.c:5:1: error: negative width in bit-field ‘<anonymous>’
screwed.c:5:1: error: struct has no named members [-pedantic]
and those are the errors the compilation should give when the code is compiled as C. The width of a bit-field must be non-negative (positive if it has a name), and a struct must have at least one named member (two, if the last one is a flexible array member). structs without tags are allowed.
You either compiled the code not as C, or your compiler is non-conforming.
When compiling as C++, the additional error
error: types may not be defined in ‘sizeof’ expressions
is generated (but the one about the struct without named members disappears).
In C++, you may not define type in a sizeof expression, and your compiler chose a less clear way of telling you.

invalid use of typedef?

To save some space in my code, I made this typedef:
typedef clients.members.at(selectedTab) currentMember;
however, g++ gives me this error:
error: expected initializer before '.' token
I figure that I'm misusing typedef, since clients.members.at(selectedTab) is a function call and not a type. Is there a way to do what I'm trying to do here?
If this is used function-local and neither clients.members nor selectedTab change between its uses, just use references. E.g.:
Member& currentMember = clients.members.at(selectedTab);
currentMember.foo();
currentMember.bar();
You seem to be trying to create a macro.
#define currentMember clients.members.at(selectedTab)
Though depending on how it's used, a simple function could be much better.
In C++0x, you can do
decltype(clients.members.at(selectedTab)) currentMember(clients.members.at(selectedTab));
However, what you're doing is fundamentally not possible. You're trying to get a value and make it a type. That's just not doable. Consider the following code:
typedef clients.members.at(selectedTab) currentMember;
currentMember a;
What on earth is a, and what does it do? You're going to have to explain more what you want.