I'm developing an audio application (in C++) and I have lots of functions that call each other that either take the number of frames (i.e. 1 mono or 2 stereo float samples) or the raw number of samples...
It is getting harder to keep track of the semantics of each function (samples or frames?) and when to mult or div by nChannels, so I would like to somehow do a typedef samples_t and frames_t (to unsigned int) and have the compiler help me out...
Is there any simple way to have an implicit conversion from frames_t to samples_t be marked as an error in C++?
You could go all out and define your own system within boost.units, or alternatively just use the BOOST_STRONG_TYPEDEF macro to create a strong typedef for each type.
Not unless frames_t and samples_t are actually different types. You could make them POD structs containing an integer, but typedefing them will have no effect.
You can't do it with typedef but boost can help you out.
If all you want is non-convertible types, BOOST_STRONG_TYPEDEF will do the trick: It will allow you to make up multiple types that are all unsigned but not convertible between each other when being passed around.
But in your particular application you may wish to consider the boost units framework where you can actually create units types, where the results from arithmetic inherit the proper units (so for example freq * time yields unitless).
Related
As far as I could find, the width of the bool type is implementation-defined. But are there any fixed-width boolean types, or should I stick to, for e.g., a uint8_t to represent a fixed-width bool?
[EDIT]
I made this python script that auto-generates a C++ class which can hold the variables I want to be able to send between a micro controller and my computer. The way it works is that it also keeps two arrays holding a pointer to each one of these variables and the sizeof each one of them. This gives me the necessary information to easily serialize and deserialize each one of these variables. For this to work however the sizeof, endianness, etc of the variable types have to be the same on both sides since I'm using the same generated code on both sides.
I don't know if this will be a problem yet, but I don't expect it to be. I have already worked with this (32bit ARM) chip before and haven't had problems sending integer and float types in the past. However it will be a few days until I'm back and can try booleans out on the chip. This might be a bigger issue later, since this code might be reused on other chips later.
So my question is. Is there a fixed width bool type defined in the standard libraries or should I just use a uint8_t to represent the boolean?
There is not. Just use uint8_t if you need to be sure of the size. Any integer type can easily be treated as boolean in C-related languages. See https://stackoverflow.com/a/4897859/1105015 for a lengthy discussion of how bool's size is not guaranteed by the standard to be any specific value.
In some projects people create custom types for everything, and in others they just use ints and floats to represent temperatures, lengths and angles.
I can see advantages and draw backs to both, and I guess it depends on the type of project you are working on if is a good idea or not to create these kinds of types.
Here is what I'm thinking of:
class SomeClass
{
Physics::Temperature TemperatureOnMoon(Geometry::Distance distanceFromSun);
Geometry::Area Shadow(Geometry::Angle xAngle, Geometry::Angle yAngle, Geometry::Triangle triangle);
};
The Temperature type would have a Fahrenheit() and Celsius() method, the Area type would have a constructor that takes two Point types and so on.
This of gives great type safety and I think it increases readability, but it also creates a lot of dependencies. Suddenly everyone who uses SomeClass has to include all these other headers and so you have to do a lot more work when your creating unit tests. It also takes time to develop all the types.
The approach using built in types are much simpler to use and have fewer dependencies:
class SomeClass
{
double TemperatureOnMoon(double distanceFromSun);
double Shadow(double xAngle, double yAngle, double triangle);
};
My question is, to what degree do you create these kinds of types? Would you prefer them in larger projects? Are there ready made libraries for this kind of stuff?
I would avoid creating new types when it's unnecessary. Here are a few issues you will have to deal with:
It hides the information about precision - like in the case of a Distance, what can an distance be? is it an integer, is it a float is it a double?
You will have problems using standard libraries - for example in the case of can you use max(distance1, distance2)? how about sorting distances? you will have to create a compare function explicitly. It also depends on how you define your type. If it's a typedef of a primitive type, you may not need to create a new compare function or max function. But it will still be confusing. But if your Distance is now a class or a struct, then you will have to overload all the operators explicitly, + - = *.....
Since you don't know if it's a floating point type or an integer you don't know if you can safely use == to compare 2 distances. They can be floating points, and if manipulated differently they may end up with a different result than in theory due to precision issues.
The number of files to maintain is going to be bigger, the building process will be unnecessary longer.
I would create new types if they don't make sense as primitives at all, and you do want to overload all the operators or not allow some. I'm struggling to find a good example, but AN example can be "a binary number" so if you define a BinaryNumber as a class/struct instead of using it as an integer that would make sense since if you had a int binaryNumber1=1, binaryNumber2=1; and somewhere along the process you do binaryNumber1+binaryNumber2 you would expect the result to be 10 instead of 2, right? So you would define a BinaryNumber class/struct and overload the operator + - * / etc.
Edit: Gfortran 6 now supports these extensions :)
I have some old f77 code that extensively uses UNIONs and MAPs. I need to compile this using gfortran, which does not support these extensions. I have figured out how to convert all non-supported extensions except for these and I am at a loss. I have had several thoughts on possible approaches, but haven't been able to successfully implement anything. I need for the existing UDTs to be accessed in the same way that they currently are; I can reimplement the UDTs but their interfaces must not change.
Example of what I have:
TYPE TEST
UNION
MAP
INTEGER*4 test1
INTEGER*4 test2
END MAP
MAP
INTEGER*8 test3
END MAP
END UNION
END TYPE
Access to the elements has to be available in the following manners: TEST%test1, TEST%test2, TEST%test3
My thoughts thusfar:
Replace somehow with fortran EQUIVALENCE.
Define the structs in C/C++ and somehow make them visible to the FORTRAN code (doubt that this is possible)
I imagine that there must have been lots of refactoring of f77 to f90/95 when the UNION and MAP were excluded from the standard. How if at all was/is this handled?
EDIT: The accepted answer has a workaround to allow memory overlap, but as far as preserving the API, it is not possible.
UNION and MAP were never part of any FORTRAN standard, they are vendor extensions. (See, e.g., http://fortranwiki.org/fortran/show/Modernizing+Old+Fortran). So they weren't really excluded from the Fortran 90/95 standard. They cause variables to overlap in memory. If the code actually uses this feature, then you will need to use equivalence. The preferred way to move data between variables of different types without conversion is the transfer intrinsic, but to you that you would have to identify every place where a conversion is necessary, while with equivalence it is taking place implicitly. Of course, that makes the code less understandable. If the memory overlays are just to save space and the equivalence of the variables is not used, then you could get rid of this "feature". If the code is like your example, with small integers, then I'd guess that the memory overlay is being used. If the overlays are large arrays, it might have been done to conserve memory. If these declarations were also creating new types, you could use user defined types, which are definitely part of Fortran >=90.
If the code is using memory equivalence of variables of different types, this might not be portable, e.g., the internal representation of integers and reals are probably different between the machine on which this code originally ran and the current machine. Or perhaps the variables are just being used to store bits. There is a lot to figure out.
P.S. In response to the question in the comment, here is a code sample. But .... to be clear ... I do not think that using equivalence is good coding pratice. With the compiler options that I normally use with gfortran to debug code, gfortran rejects this code. With looser options, gfortran will compile it. So will ifort.
module my_types
use ISO_FORTRAN_ENV
type test_p1_type
sequence
integer (int32) :: int1
integer (int32) :: int2
end type test_p1_type
type test_p2_type
sequence
integer (int64) :: int3
end type test_p2_type
end module my_types
program test
use my_types
type (test_p1_type) :: test_p1
type (test_p2_type) :: test_p2
equivalence (test_p1, test_p2)
test_p1 % int1 = 2
test_p1 % int1 = 4
write (*, *) test_p1 % int1, test_p1 % int2, test_p2 % int3
end program test
The question is whether the union was used to save space or to have alternative representations of the same data. If you are porting, see how it is used. Maybe, because the space was limited, it was written in a way where the variables had to be shared. Nowadays with larger amounts of memory, maybe this is not necessary and the union may not be required. In which case, it is just two separate types
For those just wanting to compile the code with these extensions: Gfortran now supports UNION, MAP and STRUCTURE in version 6. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56226
When creating custom typedefs for integers, is it possible for compiler to warn when you when using a default numeric type?
For example,
typedef int_fast32_t kint;
int_fast32_t test=0;//Would be ok
kint test=0; //Would be ok
int test=0; //Would throw a warning or error
We're converting a large project and the default int size on platform is 32767 which is causing some issues. This warning would warn a user to not use ints in the code.
If possible, it would be great if this would work on GCC and VC++2012.
I'm reasonably sure gcc has no such option, and I'd be surprised if VC did.
I suggest writing a program that detects references to predefined types in source code, and invoking that tool automatically as part of your build process. It would probably suffice to search for certain keywords.
Be sure you limit this to your own source files; predefined and third-party headers are likely to make extensive use of predefined types.
But I wouldn't make the prohibition absolute. There are a number of standard library functions that use predefined types. For example, in c = getchar() it makes no sense to declare c as anything other than int. And there's no problem for something like for (int i = 0; i <= 100; i ++) ...
Ideally, the goal should be to use predefined types properly. The language has never guaranteed that an int can exceed 32767. (But "proper" use is difficult or impossible to verify automatically.)
I'd approach this by doing a replace-all first and then documenting this thoroughly.
You can use a preprocessor directive:
#define int use kint instead
Note that technically this is undefined behavior and you'll run into trouble if you do this definition before including third-party headers.
I would recommend to make bulk replacement int -> old_int_t at the very beginning of your porting. This way you can continue modifying your code without facing major restrictions and at the same time have access to all places that are not yet updated.
Eventually, at the end of your work, all occurencies of old_int_t should go away.
Even if one could somehow undefine the keyword int, that would do nothing to prevent usage of that type, since there are many cases where the compiler will end up using that type. Beyond the obvious cases of integer literals, there are some more subtle cases involving integer promotion. For example, if int happens to be 64 bits, operations between two variables of type uint32_t will be performed using type int rather than uint32_t. As nice as it would be to be able to specify that some variables represent numbers (which should be eagerly promoted when practical) while others represent members of a wrapping algebraic ring (which should not be promoted), I know of no facility to do such a thing. Consequently, int is unavoidable.
i have a templated class, with the following definition:
ImageRescaleDepth<PIXEL_TYPE_INPUT, PIXEL_TYPE_OUTPUT>
This class uses templates, for pretty much everything since its supposed to be generic. Anyways i need to make a command line version of this application, to do image rescaling, currently the system is setup to handle the following types:
1BIT, 2BIT, 4BIT, unsigned 8 bit, signed 8 bit, unsigned 16 bit, signed 16 bit, unsigned 32 bit, signed 32 bit, float, double.
These are passed in by command line, and i convert them to an enum.
I cannot modify the ImageRescaleDepth class since its part of a library. and i don't exactly want to create a giant switch or eliseif block, since there would be a 100 combinations. Is it possible, i can just somehow store these types as variables? Then pass them to the constructor?
No, the type of a template class must be known at compile time, so the image types types have to be supplied to the template then. I have to say, that if this class is intended to perform conversions between many different formats, the use of template parameters to specify the conversion smacks of very poor design.
Why not to switch to OOP? You could use typeid() function to get the type name and dynamic casts then.
Maybe the use of typelists can help you. See for example boost::mpl, or simply boost/std::tuple. This is powerfull enough to generate the list of all pairs of types from your initial list. Your big switch can be handled automatically (i.e. generated) with recursive template metaprogramming (I don't know if mpl has facilities for this). However this is not trivial (I spent many hours), so if you only need to deal with this one case, it may be faster to generate the code with the help of a scripting language!