Archive for July, 2009
null pointer to member
By chys on July 19th, 2009The most straightforward implementation of a pointer to member is to store the offset:
struct Struct
{
int a;
int b;
};
The internal value of &Struct::a is 0 and &Struct::b is sizeof(int).
This leads to the illusion that &Struct::a, a valid pointer, is equal to a null pointer. Not only does this violate the standard, but also breaks many codes existing in practice.
The current (pre-0x) orthodox method of defining a cast from user-defined class to bool is not using operator bool (which leads to some unwanted consequences), but something like this:
class MyClass
{
/* ....... */
struct BooleanConvert { int val; };
operator int BooleanConvert::* () const
{
return ( /* true */ ) ? &BooleanConvert::val : 0;
}
};
It is hard to read, but the idea is simple: return a valid pointer (to member) if true, a null pointer (to member) if false.
Q: It seems both pointers evaluate to 0. How do they distinguish them?
A: In practice, a null pointer to member is represented, internally, by a value of -1 instead of 0!
So,
#include <cstdio>
#include <cstddef>
using namespace std;
struct Struct
{
int a;
};
int main()
{
union
{
int Struct::*ptr;
void * val;
};
ptr = 0;
printf ("%p\n", val);
}
the above program would output 0xffffffff (32-bit systems).
Fortunately, this does not annoy. We can safely ignore this detail (except when writing a compiler, of coz..) It seems that, except using unions or brutal memory access, there is no way to convert pointers to member to/from integers and normal pointers. (C-style casts, reinterpret_cast, etc. all reject such conversions.)
Tags: C/C++
I can’t PGO compile Firefox
By chys on July 17th, 2009A normal build of Firefox for Linux is reportedly even slower than the Win32 binary running under Wine.
The reason is reportedly that the pre-compiled binary for Windows uses PGO (profile guided optimization), which is usually not enabled under Linux. Sure, the fact that GCC does not generate as efficient codes as VC may also be a reason.[1]
Firefox also supports PGO in Linux. However, I failed at this (3.5.1). The profile-generating binary always segfaults.
Other people have encountered the same problem, even with the official PKGBUILD from Arch Linux. It is said to be a compiler problem.
Well, gave up. Maybe I’ll try it again some time later, with a more “stable” version of GCC probably.
[1] This statement only applies to the 32-bit platform. It seems GCC does a very good job on x86-64.
Profile-guided optimization is a relatively new feature. GCC began supporting it starting version 4.0; Microsoft VC 2005; and Intel C/C++/Fortran 9 (?).
A typical PGO-enabled building requires three steps:
(1) Build a profile-generating binary;
(2) Run the binary, which automatically collects useful data – branch probability, etc.
(3) Rebuild the program, using the data (“profile”) from Step 2.
With PGO, Internet Explorer reportedly gains an improvement of 8%, and Firefox 11% in JavaScript.
Tags: browser, dev, GCC, Linux, optimization
String literals
By chys on July 5th, 2009Have type const char [] in C++, but are, as an exception to the general rule, allowed to convert to type char * (though deprecated).
Have type char [] in C (even in C99 which has introduced the const keyword), but it is undefined behavior to modify them. (The standard explicitly allows storing them in read-only memory, and overlapping identical string literals.)
It seems to me that it is also possible to modify the C standard to align with C++ without altering the behavior of any existing C code. (On the other hand, we cannot modify the C++ definition of the type of string literals without affecting existing codes.)
Tags: C/C++
