Construct a 'long long' - gcc

How do you construct a long long in gcc, similar to constructing an int via int()
The following fails in gcc (4.6.3 20120306) (but passes on MSVC for example).
myFunctionCall(someValue, long long());
with error expected primary-expression before 'long' (the column position indicates the first long is the location).
A simple change
myFunctionCall(someValue, (long long)int());
works fine - that is construct an int and cast to long long - indicating that gcc doesn't like the long long ctor.
Summary Solution
To summarize the brilliant explanation below from #birryree:
many compilers don't support long long() and it may not be standards compliant
constructing long long is equivalent to the literal 0LL, so use myFunctionCall(someValue, 0LL)
alternatively use a typedef long_long_t long long then long_long_t()
lastly, consider using uint64_t if you are after a type that is exactly 64 bits on any platform, rather than a type that is at least 64 bits, but may vary on different platforms.

I wanted a definitive answer on what the expected behavior was, so I posted a question on comp.lang.c++.moderated and got some great answers in return. So a thank you goes out to Johannes Schaub, Alf P. Steinbach (both from SO), and Francis Glassborrow for some information
This is not a bug in GCC - in fact it will break across multiple compilers - GCC 4.6, GCC 4.7, and Clang complain about similar errors like primary expression expected before '(' if you try this syntax:
long long x = long long();
Some primitives have spaces, and that is not allowed if you want to use the constructor-style initialization because of binding (long() is bound, but long long() has a free long). Types with spaces in them (like long long) can not use the type()-construction form.
MSVC is more permissive here, though technically non-standard compliant (and it's not a language extension that you can disable).
Solutions/Workarounds
There are alternatives for what you want to do:
Use 0LL as your value in place of attempting long long() - they would produce the same value.
This is how most code will be written too, so it will be most understandable to anyone else reading your code.
From your comments it seems like you really want long long, so you can typedef yourself to always guarantee you have a long long type, like this:
int main() {
typedef long long MyLongLong;
long long x = MyLongLong(); // or MyLongLong x = MyLongLong();
}
Use a template to get around needing explicit naming:
template<typename TypeT>
struct Type { typedef TypeT T(); };
// call it like this:
long long ll = Type<long long>::T();
As I mentioned in my comments, you can use an aliased type, like int64_t (from <cstdint>), which across common platforms is a typedef long long int64_t. This is a more platform dependent than the previous items in this list.
int64_t is a fixed-width type that is 64-bits, which is typically how wide long long is on platforms like linux-x86 and windows-x86. long long is at least 64-bit wide, but can be longer. If your code will only run on certain platforms, or if you really need a fixed-width type, this might be a viable choice.
C++11 Solutions
Thanks to the C++ newsgroup, I learned some additional ways of doing what you want to do, but unfortunately they're only in the realm of C++11 (and MSVC10 doesn't support either, and only very new compilers either way would):
The {} way:
long long ll{}; // does the zero initialization
Using what Johannes refers to as the 'bord tools' in C++11 with std::common_type<T>
#include <type_traits>
int main() {
long long ll = std::common_type<long long>::type();
}
So is there a real difference between () and initializing with 0 for POD types?
You say this in a comment:
I don't think default ctor returns zero always - more typical behaviour is to leave memory untouched.
Well, for primitive types, that is not true at all.
From Section 8.5 of the ISO C++ Standard/2003 (don't have 2011, sorry, but this information didn't change too much):
To default-initialize an object of type T means:
— if T is a non-POD class type (clause 9), the default constructor for T is called (and the initialization is ill-formed if T has no accessible default
constructor);
— if T is an array type, each element is
default-initialized;
— otherwise, the object is zero-initialized.
The last clause is most important here because long long, unsigned long, int, float, etc. are all scalar/POD types, and so calling things like this:
int x = int();
Is exactly the same as doing this:
int x = 0;
Generated code example
Here is a more concrete example of what actually happens in code:
#include <iostream>
template<typename T>
void create_and_print() {
T y = T();
std::cout << y << std::endl;
}
int main() {
create_and_print<unsigned long long>();
typedef long long mll;
long long y = mll();
long long z = 0LL;
int mi = int();
}
Compile this with:
g++ -fdump-tree-original construction.cxx
And I get this in the generated tree dump:
;; Function int main() (null)
;; enabled by -tree-original
{
typedef mll mll;
long long int y = 0;
long long int z = 0;
int mi = 0;
<<cleanup_point <<< Unknown tree: expr_stmt
create_and_print<long long unsigned int> () >>>>>;
<<cleanup_point long long int y = 0;>>;
<<cleanup_point long long int z = 0;>>;
<<cleanup_point int mi = 0;>>;
}
return <retval> = 0;
;; Function void create_and_print() [with T = long long unsigned int] (null)
;; enabled by -tree-original
{
long long unsigned int y = 0;
<<cleanup_point long long unsigned int y = 0;>>;
<<cleanup_point <<< Unknown tree: expr_stmt
(void) std::basic_ostream<char>::operator<< ((struct __ostream_type *) std::basic_ostream<char>::operator<< (&cout, y), endl) >>>>>;
}
Generated Code Implications
So from the code tree generated above, notice that all my variables are just being initialized with 0, even if I use constructor-style default initialization, like with int mi = int(). GCC will generate code that just does int mi = 0.
My template function that just attempts to do default construction of some passed in typename T, where T = unsigned long long, also produced just a 0-initialization code.
Conclusion
So in conclusion, if you want to default construct primitive types/PODs, it's like using 0.

Related

How to use element wise integer power with Eigen

I would like to take the element wise power of an array of double with and array of int using Eigen power function.
Here is a sample code that reproduce the issue using Eigen v3.3.4 and v3.3.7:
#include <Eigen/Dense>
int main() {
Eigen::ArrayXd x(10);
Eigen::ArrayXd res(10);
Eigen::ArrayXi exponents(10);
x = Eigen::ArrayXd::Random(10);
exponents = Eigen::ArrayXi::LinSpaced(10, 0, 9);
res = Eigen::pow(x, exponents);
return (0);
}
The error message is quite long but in essence I get
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY
which does not seem appropriate to me in this context, along with
Eigen3/Eigen/src/Core/functors/BinaryFunctors.h:294:84: error: no type named ‘ReturnType’ in ‘struct Eigen::ScalarBinaryOpTraits<double, int, Eigen::internal::scalar_pow_op<double, int> >’
typedef typename ScalarBinaryOpTraits<Scalar,Exponent,scalar_pow_op>::ReturnType result_type;
As the error message indicated, you can't mix scalar types implicitly. You have to explicitly cast so that the types match:
res = Eigen::pow(x, exponents.cast<double>());
As for a specialization for integer types, the template of the power function (as a functor) is:
template<typename ScalarX,typename ScalarY, bool IsInteger =
NumTraits<ScalarX>::IsInteger&&NumTraits<ScalarY>::IsInteger>
and calls a simple pow(x,y) unless both types are integers (IsInteger), in which case there is a different specialization.
There is also an overload for an array to the power of a constant, which doesn't seem to be what you are looking for. In that case (unless ggael corrects me), you can definitely implement your own CustomBinaryOp

C++ templates reading type from configuration file at runtime

I've been trying to write a piece of code that reads a configuration file at runtime, and this file contains the names of different variables, and their type. These types are almost all builtin (int, unsigned int, char*, unsigned long long, float), with the exception of one class which stores information as binary flags.
Example configuration file contains:
Name std::string Measurement
PositionX float 0.004
PositionY float 0.002
Time unsigned long long 1521479000
Function which needs this information:
std::vector<float> xPos;
...
while( loops_over_a_file_containing_values );
...
xPos.push_back(get_information["PositionX"].extract<float>());
However, I cannot for the life of me seem to find a method in which to define these in a C++ code, most of my googling leads me to "This doesn't work" or answers that are so complicated to me that I cannot implement it in a reasonable way.
The main reason behind this is because there are a rather large number of variables with different types, and their type is needed as this function comes from another user written C++ package (which I have no way to modify in any shape or form).
So far I've looked at boost::any, boost::variant but I can't see how this could be done with those. And I'm unsure how exactly to go about this with templates either, I've tried:
template <int ModeDecider> class TypeDecider{ };
template <> class TypeDecider<0>{ public: typedef int Type; };
template <> class TypeDecider<1>{ public: typedef unsigned int Type; };
template <> class TypeDecider<2>{ public: typedef unsigned long long Type; };
template <> class TypeDecider<3>{ public: typedef float Type; };
...
std::string test1 = "unsigned long long";
std::string test2 = "1521479000";
switch( test1 ){
...
std::vector<TypeDecider<2>::Type> testvec;
testvec.push_back(static_cast<TypeDecider<2>::Type>(test2));
...}
But this gives me:
cannot convert 'std::__cxx11::string' (aka 'basic_string<char>') to 'TypeDecider<2>::Type' (aka 'unsigned long long') without a conversion operator
Which I'm not exactly sure how to go about fixing. And so far my googling-fu has yielded very little. As such, I'm here asking for help before I go to the awful step of writing a Python script in order to write the C++ script.

Is this an storage-reuse (aliasing) bug in gcc 6.2?

From what I can tell, the following code should have 100% defined behavior under any reasonable reading of the Standard for platforms which define int64_t, and where long long has the same size and representation, regardless of whether or not long long is recognized as alias-compatible.
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
typedef long long T1;
typedef int64_t T2;
#define T1FMT "%lld"
#define T1VALUE 1
#define T2VALUE 2
T1 blah3(void *p1, void *p2)
{
T1 *t1p, *t1p2;
T2 *t2p;
T1 temp;
t1p = p1;
t2p = p2;
*t1p = T1VALUE; // Write as T1
*t2p = T2VALUE; // Write as T2
temp = *t2p; // Read as T2
t1p2 = (T1*)t2p; // Visible T2 to T1 pointer conversion
*t1p2 = temp; // Write as T1
return *t1p; // Read as T1
}
T1 test3(void)
{
void *p = malloc(sizeof (T1) + sizeof (T2));
T1 result = blah3(p,p);
free(p);
return result;
}
int main(void)
{
T1 result = test3();
printf("The result is " T1FMT "\n", result);
return 0;
}
See code at https://godbolt.org/g/75oLGx (GCC 6.2 x86-64 using -std=c99 -x c -O2)
Correct code for test3 should allocate some storage, then:
Writes a long long with value 1.
Sets the Effective Type of the storage to int64_t by writing an int64_t with value 2.
Reads the storage as int64_t (its Effective Type), which should yield 2
Sets the effective type of the storage to long long by storing the a long long with the aforementioned value (which should be 2).
Read the storage as type long long, which should yield 2.
The gcc x86-64 6.2 at the godbolt site, however, does not yield 2; instead it yields 1. I didn't find any other combination of types for which gcc behaves
like this. I think what's happening is that gcc is deciding that the store to *t1p2 can be omitted because it has no effect, but it's failing to recognize that the store did have the effect of changing the Effective Type of the storage from int64_t to long long.
While I consider questionable the decision not to recognize int64_t and long long as being alias-compatible, I see nothing in the Standard that would justify gcc's failure to recognize the reuse of the storage to hold the value 2 after it had previously held the value 1. Nothing is ever read as any type other than the one with which it was written, but I think gcc is deciding that the two pointers passed to "blah" can't alias.
Am I missing anything or is that an outright bug?
The code does not violate the strict aliasing rule, as you explain. In fact, T1 and T2 could be any types (such that the assignments are not type mismatches), there's no need for them to have the same size or anything.
I would agree that outputting 1 is a compiler bug. On the godbolt site, all versions of gcc seem to have the bug, whereas clang gives the correct output.
However, with a local installation of gcc 4.9.2 (x86_64-win32-seh-rev1), I get the correct output of 2. So it seems that the problem only exists in some builds of gcc.

Deriving from std::function vs creating a functor manually

I am trying to create a queue of callable elements with state so I can store the callable element (with an integer indicating when it should be called) and then call it later (after checking the stored integer within it).
I have been reading about functors and the std::function template for the past few days and I am wondering which one of the following two options would be better in terms of both memory and performance (which is better for each, if different).
1st Option:
class UpdateFunction : public std::function<bool(unsigned long long int)> {
public:
unsigned long long int _intendedTime;
};
void main()
{
typedef std::deque<UpdateFunction> UpdateQueue;
UpdateQueue _updateQueue;
_updateQueue.push_back(UpdateFunction([](unsigned long long int time)->bool{return outsideFunction(time);}));
_updateQueue.back()._intendedTime = 10;
}
2nd Option:
class UpdateFunction {
bool (*_fn)(unsigned long long int);
unsigned long long int _intendedTime;
UpdateFunction::UpdateFunction(bool (*fn)(unsigned long long int), unsigned long long int time)
: _fn(fn),
_intendedTime(time)
{
}
bool operator()(unsigned long long int time)
{
return _fn(time);
}
};
void main()
{
typedef std::deque<UpdateFunction> UpdateQueue;
UpdateQueue _updateQueue;
_updateQueue.push_back(UpdateFunction(outsideFunction, 10));
}
I have never seen any code where someone derives from std::function so I'm not even sure this would work as expected.
An answer which comes close to what I'm trying to do is this: https://stackoverflow.com/a/9050114/4076418, but I don't need variable arguments (actually, I have only one single signature, which is in the code above), so I thought it might be better to just derive from std::function instead of contain an instance of it. To be honest, I have no idea how slow or fast std::function is; I've read mentions of type erasure but I'm still trying to figure out what that is.
NB: I am a C++ beginner and I'm trying to wrap my head around references and move semantics, so I apologize if there are obvious errors in the code, or if the coding style is horrible.
I would go with a variant of option 2. This gives you the flexibility of function but avoids the headache of subclassing and needing to deal with the constructors.
struct UpdateFunction {
std::function<bool(unsigned long long int)> fn;
unsigned long long int _intendedTime;
};
You don't even need a special constructor, you can just say
queue.push_back(UpdateFunction{outsideFunction, 10});

Why declare int a constexpr

While watching a C++11 tutorial video linked on isocpp.org I noticed something:
constexpr int windowWidth{800}, windowHeight{600};
What is the point in declaring these int variables as constexpr, and not just const?
Nice video Vittorio!
Here is a summary of the difference between declaring an int const and constexpr:
int get_int(); // Some run time function that returns int
template <int N> // example use requiring a compile time int
struct test {};
const int w = get_int(); // initialized at run time
const int x = 5; // initialized at compile time
constexpr int y = get_int(); // error, can not initialize at compile time
constexpr int z = 6; // initialized at compile time
int
main()
{
test<w> tw; // error, w is not a compile time constant
test<x> tx; // ok, x is a compile time constant
test<y> ty; // error, there is no compile time constant named y
test<z> tz; // ok, z is a compile time constant
}
When you use constexpr, you require that the initialization happens at compile time, lest you will get a compile time error. When you use const, you allow the initialization to happen at run time, though it will still happen at compile time if the initializer is itself a compile time constant.
If you have a const int, the code reviewer must look at the initialization (following back to the original if this is a copy of a const int) to know if that const int is a compile time constant, or a run time constant.
If you have a constexpr int, the code reviewer can immediately assume that it is a compile time constant without analyzing how it was initialized. If that assumption turns out to be false, the compiler will flag it as an error.
<Disclaimer>
In the comments below Kerrek SB correctly points out that I've played "fast and loose" with the terminology in this answer. I've done so in an effort to make the answer short and understandable. What I'm calling "initialized at compile time" and "compile time constant" are what the standard in section 5.19 "Constant expressions" [expr.const] refers to as integral constant expressions.
Integral constant expressions are initialized with what is called constant initialization, which together with zero-initialization is referred to as static initialization ([basic.start.init]/p2).
Any deviations between what I write here and what appears in the standard are accidental, and what is in the standard is correct.
</Disclaimer>
I'm the author of the video.
Intent.
constexpr clearly expresses the intent of a compile-time immutable value. const doesn't really mean compile-time immutable value.
Both modifiers can be casted away, but that results in undefined behavior. Check DyP's comment for more information.
When using C++11, in my opinion, the first keyword that should come to mind when dealing with compile-time values is not const but constexpr.
The code would behave exactly the same without constexpr, or with const in place of constexpr.
But when you take a look at the code, and see constexpr int windowWidth; you can be 100%
sure that's an immutable constant that will never change during run-time.
In my second tutorial video, there's an addendum on constexpr in the first three minutes, that shows constexpr functions and more constexpr examples/explanations.

Resources