What header file needs to be included for using nullptr in g++? - g++

I am using g++ 4.4.1 and want to use nullptr, but I am not being able to find which header file is required to be included. It does not seem to be keyword either, because my attempt to use it is rejected as
error: 'nullptr' was not declared in this scope

GCC 4.4.1 does not support nullptr.
Support for nullptr was added in GCC 4.6.0:
http://gcc.gnu.org/gcc-4.6/changes.html
Improved experimental support for the
upcoming C++0x ISO C++ standard,
including support for nullptr (thanks
to Magnus Fromreide), noexcept,
unrestricted unions, range-based for
loops (thanks to Rodrigo Rivas Costa),
implicitly deleted functions and
implicit move constructors.
For earlier versions of GCC, if you want to experiment with nullptr you can try the workaround in this SO question:
Can nullptr be emulated in GCC?

I would recommend not using nullptr as defined above, because it can be dangerous. If you want to use nullptr the following statement should be true.
sizeof(nullptr) == sizeof(void*) == sizeof(any pointer)
However, sizeof(nullptr) (as defined above) will not comply to this rule. It will actually evaluate to sizeof(bad nullptr) = 1.
This is a correct implementation.
#pragma once
namespace std
{
//based on SC22/WG21/N2431 = J16/07-0301
struct nullptr_t
{
template<typename any> operator any * () const
{
return 0;
}
template<class any, typename T> operator T any:: * () const
{
return 0;
}
#ifdef _MSC_VER
struct pad {};
pad __[sizeof(void*)/sizeof(pad)];
#else
char __[sizeof(void*)];
#endif
private:
// nullptr_t();// {}
// nullptr_t(const nullptr_t&);
// void operator = (const nullptr_t&);
void operator &() const;
template<typename any> void operator +(any) const
{
/*I Love MSVC 2005!*/
}
template<typename any> void operator -(any) const
{
/*I Love MSVC 2005!*/
}
};
static const nullptr_t __nullptr = {};
}
#ifndef nullptr
#define nullptr std::__nullptr
#endif

I use -std=c++0x to enable the nullptr feature with gcc 4.6.3

If you don't have the latest gcc which supports C++11 , try using NULL instead of nullptr.

Related

#pragma GCC unroll with compile-time argument

Is there a way to unroll a loop in GCC based on compile-time (e.g., template) parameter?
The following does not compile, unless I replace unroll(N) with a concrete integer like unroll(8)
template<int N>
void fun ()
{
#pragma GCC unroll(N)
for (...)
// body
}

Missing a warning on unexpected implicit enum casts

I have made a new Objective-C project in Xcode 10.2.1 (Apple LLVM version 10.0.1 (clang-1001.0.46.4)), and have a code like this inside main.m:
#import <Foundation/Foundation.h>
typedef NS_ENUM(NSUInteger, Fruit) {
Apple,
Banana,
Coconut,
};
void boolArg(BOOL b) { if (b) puts("boolArg"); }
void shortArg(short s) { if (s > 0) puts("shortArg"); }
void fruitArg(Fruit f) { if (f == Banana) puts("fruitArg"); }
int main() {
Fruit f = Coconut;
// NEED WARN: passing Fruit instead of a boolean, unexpected cast
boolArg(f);
// NEED WARN: fruit (NSUInteger) instead of a short, unexpected cast losing precision
shortArg(f);
// NEED WARN: passing boolean instead of a Fruit, unexpected cast
fruitArg(YES);
return 0;
}
In my codebase I'd like to protect from such implicit casts. Is it possible to enable some clang warning to catch this?
What I tried so far and it didn't help:
enabled "Implicit Signedness Conversions" warning;
added to "Other Warnings Flags": -Wall, -Wextra;
change main.m to main.mm (to compile with Objective-C++) - only catches the last fruitArg call.

Swift doesn't allow function overloading in objective-c or c headers

I have some swift code, which is not really important in context of question.
Also i have Objective-C bridging header ObjC-Swift-Bridging.h:
#import "my_objective_cpp_header.h"
And i have free C/C++ - style functions in that header:
inline void foo() {
}
inline void foo(int i) {
}
When i try to compile it in xcode 9.2 with enabled swift 4.0 i get error:
my_objective_cpp_header.h:29:13: error: redefinition of 'foo'
inline void foo(int i){
^
my_objective_cpp_header.h:26:13: note: previous definition is here
inline void foo() {
^
ObjC-Swift-Bridging.h:22:9: note: in file included from ObjC-Swift-Bridging.h:22:
#import "my_objective_cpp_header.h"
The same happens if i put these functions to C/C++ header and write
#include "my_cpp_header.h"
into ObjC-Swift-Bridging.h
So... Swift doesn't support code which was supported in Objective-C++? Did i miss something?

Working with structures in C++/CLI

I have following code
ref class A
{
typedef ref struct All
{
std::string x;
}All_t;
};
in my program I am using it in following manner
A::All_t t;
t.X = "H";
This declaration throwing error as
error C4368: cannot define 'x' as a member of managed 'A::All': mixed types are not supported
I understand that I am declaring native varible inside managed code which is not allowed but now I would like to know changes I will need to make to make my structure suitable to managed project.
Thanks.
I'm assuming you originally had std::string x; not std::string *x (since using the pointer to string does not generate that error). You are not allowed to directly embed a native type in a managed type, but you are allowed to indirectly have one (via a pointer) See:
http://msdn.microsoft.com/en-us/library/xhfb39es(v=vs.80).aspx
After I fixed the compiler errors in your sample, it builds without error:
#include "stdafx.h"
#include <string>
using namespace System;
ref class A
{
public:
typedef ref struct All
{
std::string * x;
}All_t;
};
int main(array<System::String ^> ^args)
{
A::All_t t;
t.x = new std::string("H");
return 0;
}

Obj-C++: template metafunction for recognizing Objective-C classes?

Using Objective-C++, can I write a C++ IsObjectiveCClass<T> template metafunction such that IsObjectiveCClass<T>::value is true if and only if T is an Objective-C class?
Exactly what are ObjC classes from the viewpoint of the C / C++ subset of the language? When used in a C / C++ context, MyClass* pointers seem to behave like ordinary C pointers; does that mean that MyClass is also a C type?
Here is a simplistic solution that should work in most (if not all? Can anyone think of when this might fail?) cases (it uses clang 3.0 via xcode 4.2 - use typedefs instead of using aliases for earlier clang versions):
template<class T> struct IsObjectiveCClass
{
using yesT = char (&)[10];
using noT = char (&)[1];
static yesT choose(id);
static noT choose(...);
static T make();
enum { value = sizeof(choose(make())) == sizeof(yesT) };
};
You can read my most recent rant about ObjC++ in this question. Avoid it as much as you can possibly get away with. Definitely don't try to integrate Objective-C into C++ template metaprogramming. The compiler might actually rip a hole in space.
Hyperbole aside, what you're trying to do is likely impossible. Objective-C classes are just structs. (C++ classes actually just structs too.) There's not much compile-time introspection available.
An id is a C pointer to a struct objc_object. At runtime, every object is an id, no matter its class.
typedef struct objc_class *Class;
typedef struct objc_object {
Class isa;
} *id;
As with the accepted answer, you can test whether the type is convertible to id, in C++17:
template <typename T>
struct is_objc_ptr : std::integral_constant<bool,
std::is_convertible_v<T, id> && !std::is_null_pointer_v<T>> {};
template <typename T>
constexpr bool is_objc_ptr_v = is_objc_ptr<T>::value;
Testing:
static_assert(!is_objc_ptr_v<nullptr_t>);
static_assert(!is_objc_ptr_v<int>);
static_assert(!is_objc_ptr_v<char *>);
static_assert(is_objc_ptr_v<id>);
static_assert(is_objc_ptr_v<NSObject *>);
I don't know of a way to discover ObjC inheritance relationships at compile-time; in theory they're changeable at runtime so you would have to query the runtime.
If you look at the implementation of the C++ STL library in Xcode, you can follow the template specialization models of others like std::is_integral or std::is_floating_point:
template <class T> struct isObjcObject : public std::false_type { };
template <> struct isObjcObject<id> : public std::true_type { };
where std::false_type and std::true_type are defined in the <type_traits> header file.
If for whatever reason you don't have std::false_type and std::true_type (depending on your C++ version), you can define them yourself as such:
template<bool B> struct boolean_constant { static constexpr const bool value = B; };
template <class T> struct isObjcObject : public boolean_constant<false> { };
template <> struct isObjcObject<id> : public boolean_constant<true> { };
Note that you can also do this for Objective-C classes too:
template <class T> struct isObjcClass : public std::false_type { };
template <> struct isObjcClass<Class> : public std::true_type { };
I would create a template specialisation for 'id' and 'NSObject*', but you'll always be working against the language because the ObjC type system is not the C++ type system.
Similar to Doug's answer, but slightly simpler:
template<typename T>
inline constexpr bool is_objc_v = std::is_convertible_v<id,T>;
Checking that id is convertible to T – instead of the other way around – avoids false positives for C++ types which have a user-defined implicit conversion to an Obj-C type.