text:
I'm pleased to announce that Denis Bulichenko has translated this article into Russian! It has been published in RSDN. The complete article will soon be available on-line. I'm deeply indebted to you, Denis.
Standard C++ does not have true object-oriented function pointers. This is unfortunate, because object-oriented function pointers, also called 'closures' or 'delegates', have proved their value in similar languages. In Delphi (Object Pascal), they are the basis for Borland's Visual Component Library (VCL). More recently, C# has popularized the delegate concept, contributing to the success of that language. For many applications, delegates simplify the use of elegant design patterns (Observer, Strategy, State[GoF]) composed of very loosely coupled objects. There can be no doubt that such a feature would be useful in standard C++.
Instead of delegates, C++ only provides member function pointers. Most C++ programmers have never used member function pointers, and with good reason. They have their own bizarre syntax (the ->* and .* operators, for example), it's hard to find accurate information about them, and most of the things you can do with them could be done better in some other way. This is a bit scandalous: it's actually easier for a compiler writer to implement proper delegates than it is to implement member function pointers!
In this article, I'll "lift the lid" on member function pointers. After a recap of the syntax and idiosyncrasies of member function pointers, I'll explain how member function pointers are implemented by commonly-used compilers. I'll show how compilers could implement delegates efficiently. Finally, I will show how I used this clandestine knowledge of member function pointers to make an implementation of delegates that is optimally efficient on most C++ compilers. For example, invoking a single-target delegate on Visual C++ (6.0, .NET, and .NET 2003) generates just two lines of assembly code!
We begin with a review of function pointers. In C, and consequently in C++, a function pointer called my_func_ptr that points to a function taking an int and a char * and returning a float, is declared like this:
char *
float (*my_func_ptr)(int, char *); // To make it more understandable, I strongly recommend that you use a typedef. // Things can get particularly confusing when // the function pointer is a parameter to a function. // The declaration would then look like this: typedef float (*MyFuncPtrType)(int, char *); MyFuncPtrType my_func_ptr;
Note that there is a different type of function pointer for each combination of arguments. On MSVC, there is also a different type for each of the three different calling conventions: __cdecl, __stdcall, and __fastcall. You make your function pointer point to a function float some_func(int, char *) like this:
float some_func(int, char *)
my_func_ptr = some_func;
When you want to invoke the function that you stored, you do this:
(*my_func_ptr)(7, "Arbitrary String");
You are allowed to cast from one type of function pointer to another. But you are not allowed to cast a function pointer to a void * data pointer. The other allowable operations are trivial. A function pointer can be set to 0 to mark it as a null pointer. The full range of comparison operators are available (==, !=, <, >, <=, >=), and you can also test for null pointers using ==0 or via an implicit cast to bool. Interestingly, a function pointer can be used as a non-type template parameter. This is fundamentally different from a type parameter, and is also different from an integral non-type parameter. It is instantiated based on name rather than type or value. Name-based template parameters are not supported by all compilers, not even by all those with support for partial template specialization.
void *
In C, the most common uses of function pointers are as parameters to library functions like qsort, and as callbacks for Windows functions, etc. They have many other applications as well. The implementation of function pointers is simple: they are just "code pointers": they hold the starting address of an assembly-language routine. The different types of function pointers exist only to ensure that the correct calling convention is used.
In C++ programs, most functions are member functions; that is, they are part of a class. You are not allowed to use an ordinary function pointer to point to a member function; instead, you have to use a member function pointer. A member function pointer to a member function of class SomeClass, with the same arguments as before, is declared like this:
float (SomeClass::*my_memfunc_ptr)(int, char *); // For const member functions, it's declared like this: float (SomeClass::*my_const_memfunc_ptr)(int, char *) const;
Notice that a special operator (::*) is used, and that SomeClass is part of the declaration. Member function pointers have a horrible restriction: they can only point to member functions of a single class. There is a different type of member function pointer for each combination of arguments, for both types of const-ness, and for each class. On MSVC, there is also a different type for each of the four different calling conventions: __cdecl, __stdcall, __fastcall, and __thiscall. (__thiscall is the default. Interestingly, there is no documented __thiscall keyword, but it sometimes shows up in error messages. If you use it explicitly, you'll get an error message stating that it is reserved for future use.) If you're using member function pointers, you should always use a typedef to avoid confusion.
You make your function pointer point to a function float SomeClass::some_member_func(int, char *) like this:
float SomeClass::some_member_func(int, char *)
my_memfunc_ptr = &SomeClass::some_member_func; // This is the syntax for operators: my_memfunc_ptr = &SomeClass::operator !; // There is no way to take the address of a constructor or destructor
Some compilers (most notably MSVC 6 and 7) will let you omit the &, even though it is non-standard and confusing. More standard-compliant compilers (e.g., GNU G++ and MSVC 8 (a.k.a. VS 2005)) require it, so you should definitely put it in. To invoke the member function pointer, you need to provide an instance of SomeClass, and you must use the special operator ->*. This operator has a low precedence, so you need to put it in parentheses:
SomeClass *x = new SomeClass; (x->*my_memfunc_ptr)(6, "Another Arbitrary Parameter"); // You can also use the .* operator if your class is on the stack. SomeClass y; (y.*my_memfunc_ptr)(15, "Different parameters this time");
Don't blame me for the syntax -- it seems that one of the designers of C++ loved punctuation marks!
C++ added three special operators to the C language specifically to support member pointers. ::* is used in declaring the pointer, and ->* and .* are used in invoking the function that is pointed to. It seems that extraordinary attention was paid to an obscure and seldom-used part of the language. (You're even allowed to overload the ->* operator, though why you want to do such a thing is beyond my comprehension. I only know of one such usage [Meyers].)
A member function pointer can be set to 0, and provides the operators == and !=, but only for member function pointers of the same class. Any member function pointer can be compared with 0 to see if it is null. [Update, March 2005: This doesn't work on all compilers. On Metrowerks MWCC, a pointer to the first virtual function of a simple class will be equal to zero!] Unlike simple function pointers, the inequality comparisons (<, >, <=, >=) are not available. Like function pointers, they can be used as non-type template parameters, but this seems to work on fewer compilers.
There are some weird things about member function pointers. Firstly, you can't use a member function to point to a static member function. You have to use a normal function pointer for that. (So the name "member function pointer" is a bit misleading: they're actually "non-static member function pointers".) Secondly, when dealing with derived classes, there are some surprises. For example, the code below will compile on MSVC if you leave the comments intact:
class SomeClass { public: virtual void some_member_func(int x, char *p) { printf("In SomeClass"); }; }; class DerivedClass : public SomeClass { public: // If you uncomment the next line, the code at line (*) will fail! // virtual void some_member_func(int x, char *p) { printf("In DerivedClass"); }; }; int main() { // Declare a member function pointer for SomeClass typedef void (SomeClass::*SomeClassMFP)(int, char *); SomeClassMFP my_memfunc_ptr; my_memfunc_ptr = &DerivedClass::some_member_func; // ---- line (*) }
Curiously enough, &DerivedClass::some_member_func is a member function pointer of class SomeClass. It is not a member of DerivedClass! (Some compilers behave slightly differently: e.g., for Digital Mars C++, &DerivedClass::some_member_func is undefined in this case.) But, if DerivedClass overrides some_member_func, the code won't compile, because &DerivedClass::some_member_func has now become a member function pointer of class DerivedClass!
Casting between member function pointers is an extremely murky area. During the standardization of C++, there was a lot of discussion about whether you should be able to cast a member function pointer from one class to a member function pointer of a base or derived class, and whether you could cast between unrelated classes. By the time the standards committee made up their mind, different compiler vendors had already made implementation decisions which had locked them into different answers to these questions. According to the Standard (section 5.2.10/9), you can use reinterpret_cast to store a member function for one class inside a member function pointer for an unrelated class. The result of invoking the casted member function is undefined. The only thing you can do with it is cast it back to the class that it came from. I'll discuss this at length later in the article, because it's an area where the Standard bears little resemblance to real compilers.
On some compilers, weird stuff happen even when converting between member function pointers of base and derived classes. When multiple inheritance is involved, using reinterpret_cast to cast from a derived class to a base class may or may not compile, depending on what order the classes are listed in the declaration of the derived class! Here's an example:
class Derived: public Base1, public Base2 // case (a) class Derived2: public Base2, public Base1 // case (b) typedef void (Derived::* Derived_mfp)(); typedef void (Derived2::* Derived2_mfp)(); typedef void (Base1::* Base1mfp) (); typedef void (Base2::* Base2mfp) (); Derived_mfp x;
For case (a), static_cast<Base1mfp>(x) will work, but static_cast<Base2mfp>(x) will fail. Yet for case (b), the opposite is true. You can safely cast a member function pointer from a derived class to its first base class only! If you try, MSVC will issue warning C4407, while Digital Mars C++ will issue an error. Both will protest if you use reinterpret_cast instead of static_cast, but for different reasons. But, some compilers will be perfectly happy no matter what you do. Beware!
There's another interesting rule in the standard: you can declare a member function pointer before the class has been defined. You can even invoke a member function of this incomplete type! This will be discussed later in the article. Note that a few compilers can't cope with this (early MSVC, early CodePlay, LVMM).
It's worth noting that, as well as member function pointers, the C++ standard also provides member data pointers. They share the same operators, and some of the same implementation issues. They are used in some implementations of stl::stable_sort, but I'm not aware of many other sensible uses.
By now, I've probably convinced you that member function pointers are somewhat bizarre. But what are they useful for? I did an extensive search of published code on the web to find out. I found two common ways in which member function pointers are used:
They also have trivial uses in one-line function adaptors in the STL and Boost libraries, allowing you to use member functions with the standard algorithms. In such cases, they are used at compile-time; usually, no function pointers actually appear in the compiled code. The most interesting application of member function pointers is in defining complex interfaces. Some impressive things can be done in this way, but I didn't find many examples. Most of the time, these jobs can be performed more elegantly with virtual functions or with a refactoring of the problem. But by far, the most famous uses of member function pointers are in application frameworks of various kinds. They form the core of MFC's messaging system.
When you use MFC's message map macros (e.g., ON_COMMAND), you're actually populating an array containing message IDs and member function pointers (specifically, CCmdTarget::* member function pointers). This is the reason that MFC classes must derive from CCmdTarget if they want to handle messages. But the various message handling functions have different parameter lists (for example, OnDraw handlers have CDC * as the first parameter), so the array must contain member function pointers of various types. How does MFC deal with this? They use a horrible hack, putting all the possible member function pointers into an enormous union, to subvert the normal C++ type checking. (Look up the MessageMapFunctions union in afximpl.h and cmdtarg.cpp for the gory details.) Because MFC is such an important piece of code, in practice, all C++ compilers support this hack.
In my searches, I was unable to find many examples of good usage of member function pointers, other than at compile time. For all their complexity, they don't add much to the language. It's hard to escape the conclusion that C++ member function pointers have a flawed design.
In writing this article, I have one key point to make: It is absurd that the C++ Standard allows you to cast between member function pointers, but doesn't allow you to invoke them once you've done it. It's absurd for three reasons. Firstly, the cast won't always work on many popular compilers (so, casting is standard, but not portable). Secondly, on all compilers, if the cast is successful, invoking the cast member function pointer behaves exactly as you would hope: there is no need for it to be classed as "undefined behavior". (Invocation is portable, but not standard!) Thirdly, allowing the cast without allowing invocation is completely useless; but if both cast and invocation are possible, it's easy to implement efficient delegates, with a huge benefit to the language.
To try to convince you of this controversial assertion, consider a file consisting solely of the following code. This is legal C++.
class SomeClass; typedef void (SomeClass::* SomeClassFunction)(void); void Invoke(SomeClass *pClass, SomeClassFunction funcptr) { (pClass->*funcptr)(); };
Note that the compiler has to produce assembly code to invoke the member function pointer, knowing nothing about the class SomeClass. Clearly, unless the linker does some _extremely_ sophisticated optimization, the code must work correctly regardless of the actual definition of the class. An immediate consequence is that you can safely invoke a member function pointer that's been cast from a completely different class.
To explain the other half of my assertion, that casting doesn't work the way the standard says it should, I need to discuss in detail exactly how compilers implement member function pointers. This will also help to explain why the rules about the use of member function pointers are so restrictive. Accurate documentation about member function pointers is hard to obtain, and misinformation is common, so I've examined the assembly code produced by a large range of compilers. It's time to get our hands dirty.
A member function of a class is a bit different from a standard C function. As well as the declared parameters, it has a hidden parameter called this, which points to the class instance. Depending on the compiler, this might be treated internally as a normal parameter, or it might receive special treatment. (For example, in VC++, this is usually passed using the ECX register). this is fundamentally different to normal parameters. For virtual functions, it controls at runtime which function is executed. Even though a member function is a real function underneath, there is no way in standard C++ to make an ordinary function behave like a member function: there's no thiscall keyword to make it use the correct calling convention. Member functions are from Mars, ordinary functions are from Venus.
You'd probably guess that a "member function pointer", like a normal function pointer, just holds a code pointer. You would be wrong. On almost all compilers, a member function pointer is bigger than a function pointer. Most bizarrely, in Visual C++, a member function pointer might be 4, 8, 12, or 16 bytes long, depending on the nature of the class it's associated with, and depending on what compiler settings are used! Member function pointers are more complex than you might expect. But it was not always so.
Let's go back in time to the early 1980's. When the original C++ compiler (CFront) was originally developed, it only had single inheritance. When member function pointers were introduced, they were simple: they were just function pointers that had an extra this parameter as the first argument. When virtual functions were involved, the function pointer pointed to a short bit of 'thunk' code. (Update, Oct 04: A discussion on comp.lang.c++.moderated has established that CFront didn't actually use thunks, it was much less elegant. But it could have used this method, and pretending that it did, makes the following discussion a bit easier to understand.)
This idyllic world was shattered when CFront 2.0 was released. It introduced templates and multiple inheritance. Part of the collateral damage of multiple inheritance was the castration of member function pointers. The problem is, with multiple inheritance, you don't know what this pointer to use until you make the call. For example, suppose you have the four classes defined below:
class A { public: virtual int Afunc() { return 2; }; }; class B { public: int Bfunc() { return 3; }; }; // C is a single inheritance class, derives only from A class C: public A { public: int Cfunc() { return 4; }; }; // D uses multiple inheritance class D: public A, public B { public: int Dfunc() { return 5; }; };
Suppose we create a member function pointer for class C. In this example, Afunc and Cfunc are both member functions of C, so our member function pointer is allowed to point to Afunc or Cfunc. But Afunc needs a this pointer that points to C::A (which I'll call Athis), while Cfunc needs a this pointer that points to C (which I'll call Cthis). Compiler writers deal with this situation by a trick: they ensure that A is physically stored at the start of C. This means that Athis == Cthis. We only have one this to worry about, and all's well with the world.
Athis == Cthis
Now, suppose we create a member function pointer for class D. In this case, our member function pointer is allowed to point to Afunc, Bfunc, or Dfunc. But Afunc needs a this pointer that points to D::A, while Bfunc needs a this pointer that points to D::B. This time, the trick doesn't work. We can't put both A and B at the start of D. So, a member function pointer to D needs to specify not only what function to call, but also what this pointer to use. The compiler does know how big A is, so it can convert an Athis pointer into a Bthis just by adding an offset (delta = sizeof(A)) to it.
delta = sizeof(A)
If you're using virtual inheritance (i.e., virtual base classes), it's much worse, and you can easily lose your mind trying to understand it. Typically, the compiler uses a virtual function table ('vtable') which stores for each virtual function, the function address, and the virtual_delta: the amount in bytes that needs to be added to the supplied this pointer to convert it into the this pointer that the function requires.
None of this complexity would exist if C++ had defined member function pointers a bit differently. In the code above, the complexity only comes because you are allowed to refer to A::Afunc as D::Afunc. This is probably bad style; normally, you should be using base classes as interfaces. If you were forced to do this, then member function pointers could have been ordinary function pointers with a special calling convention. IMHO, allowing them to point to overridden functions was a tragic mistake. As payment for this rarely-used extra functionality, member function pointers became grotesque. They also caused headaches for the compiler writers who had to implement them.
So, how do compilers typically implement member function pointers? Here are some results obtained by applying the sizeof operator to various structures (an int, a void * data pointer, a code pointer (i.e., a pointer to a static function), and a member function pointer to a class with single-, multiple-, virtual- inheritance, or unknown (i.e., forward declared)) for a variety of 32, 64 and 16-bit compilers.
# Or 4,8, or 12 if the __single/ __multi/ __virtual_inheritance keyword is used.
The compilers are Microsoft Visual C++ 4.0 to 7.1 (.NET 2003), GNU G++ 3.2 (MingW binaries, www.mingw.org), Borland BCB 5.1 (www.borland.com), Open Watcom (WCL) 1.2 (www.openwatcom.org), Digital Mars (DMC) 8.38n (www.digitalmars.com), Intel C++ 8.0 for Windows IA-32, Intel C++ 8.0 for Itanium (www.intel.com), IBM XLC for AIX (Power, PowerPC), Metrowerks Code Warrior 9.1 for Windows (www.metrowerks.com), and Comeau C++ 4.3 (www.comeaucomputing.com). The data for Comeau applies to all their supported 32-bit platforms (x86, Alpha, SPARC, etc.). The 16-bit compilers were also tested in four DOS configurations (tiny, compact, medium, and large) to show the impact of various code and data pointer sizes. MSVC was also tested with an option (/vmg) that gives "full generality for pointers to members". (If you have a compiler from a vendor that is not listed here, please let me know. Results for non-x86 processors are particularly valuable.)
Amazing, isn't it? Looking at this table, you can readily see how easy it is to write code that will work in some circumstances but fail to compile in others. The internal implementations are obviously very different between compilers; in fact, I don't think that any other language feature has such a diversity of implementation. Looking in detail at the implementations reveals some surprising nastiness.
For almost all compilers, two fields I've called delta and vindex are used to adjust the provided this pointer into an adjustedthis which is passed to the function. For example, here is the technique used by Watcom C++ and Borland:
struct BorlandMFP { // also used by Watcom CODEPTR m_func_address; int delta; int vindex; // or 0 if no virtual inheritance }; if (vindex==0) adjustedthis = this + delta; else adjustedthis = *(this + vindex -1) + delta CALL funcadr
If virtual functions are used, the function pointer points to a two-instruction 'thunk' to determine the actual function to be called. Borland applies an optimization: if it knows that the class only used single inheritance, it knows that delta and vindex will always be zero, so it can skip the calculation in this most common case. Importantly, it only changes the invocation calculation, it does not change the structure itself.
Many other compilers use the same calculation, often with a minor reordering of the structure.
// Metrowerks CodeWarrior uses a slight variation of this theme. // It uses this structure even in Embedded C++ mode, in which // multiple inheritance is disabled! struct MetrowerksMFP { int delta; int vindex; // or -1 if no virtual inheritance CODEPTR func_address; }; // An early version of SunCC apparently used yet another ordering: struct { int vindex; // or 0 if a non-virtual function CODEPTR func_address; // or 0 if a virtual function int delta; };
Metrowerks doesn't seem to inline the calculation. Instead, it's performed in a short 'member function invoker' routine. This reduces code size a little but makes their member function pointers a bit slower.
Digital Mars C++ (formerly Zortech C++, then Symantec C++) uses a different optimization. For single-inheritance classes, a member function pointer is just the address of the function. When more complex inheritance is involved, the member function pointer points to a 'thunk' function, which performs the necessary adjustments to the this pointer, and then calls the real member function. One of these little thunk functions is created for every member function that's involved in multiple inheritance. This is easily my favorite implementation.
struct DigitalMarsMFP { // Why doesn't everyone else do it this way? CODEPTR func_address; };
Current versions of the GNU compiler use a strange and tricky optimization. It observes that, for virtual inheritance, you have to look up the vtable in order to get the voffset required to calculate the this pointer. While you're doing that, you might as well store the function pointer in the vtable. By doing this, they combine the m_func_address and m_vtable_index fields into one, and they distinguish between them by ensuring that function pointers always point to even addresses but vtable indices are always odd:
// GNU g++ uses a tricky space optimisation, also adopted by IBM's VisualAge and XLC. struct GnuMFP { union { CODEPTR funcadr; // always even int vtable_index_2; // = vindex*2+1, always odd }; int delta; }; adjustedthis = this + delta if (funcadr & 1) CALL (* ( *delta + (vindex+1)/2) + 4) else CALL funcadr
The G++ method is well documented, so it has been adopted by many other vendors, including IBM's VisualAge and XLC compilers, recent versions of Open64, Pathscale EKO, and Metrowerks' 64-bit compilers. A simpler scheme used by earlier versions of GCC is also very common. SGI's now discontinued MIPSPro and Pro64 compilers, and Apple's ancient MrCpp compiler used this method. (Note that the Pro64 compiler has become the open source Open64 compiler).
struct Pro64MFP { short delta; short vindex; union { CODEPTR funcadr; // if vindex==-1 short __delta2; } __funcadr_or_delta2; }; // If vindex==0, then it is a null pointer-to-member.
Compilers based on the Edison Design Group front-end (Comeau, Portland Group, Greenhills) use a method that is almost identical. Their calculation is (PGI 32-bit compilers):
// Compilers using the EDG front-end (Comeau, Portland Group, Greenhills, etc) struct EdisonMFP{ short delta; short vindex; union { CODEPTR funcadr; // if vindex=0 long vtordisp; // if vindex!=0 }; }; if (vindex==0) { adjustedthis=this + delta; CALL funcadr; } else { adjustedthis = this+delta + *(*(this+delta+vtordisp) + vindex*8); CALL *(*(this+delta+funcadr)+vindex*8 + 4); };
Most compilers for embedded systems don't allow multiple inheritance. Thus, these compilers avoid all the quirkiness: a member function pointer is just a normal function pointer with a hidden 'this' parameter.
Microsoft compilers use an optimization that is similar to Borland's. They treat single inheritance with optimum efficiency. But unlike Borland, the default is to discard the entries which will always be zero. This means that single-inheritance pointers are the size of simple function pointers, multiple inheritance pointers are larger, and virtual inheritance pointers are larger still. This saves space. But it's not standard-compliant, and it has some bizarre side-effects.
Firstly, casting a member function pointer between a derived class and a base class can change its size! Consequently, information can be lost. Secondly, when a member function is declared before its class is defined, the compiler has to work out how much space to allocate to it. But it can't do this reliably, because it doesn't know the inheritance nature of the class until it's defined. It has to guess. If it guesses wrongly in one source file, but correctly in another, your program will inexplicably crash at runtime. So, Microsoft added some reserved words to their compiler: __single_inheritance, __multiple_inheritance, and __virtual_inheritance. They also added a compiler switch: /vmg, which makes all MFPs the same size, by retaining the missing zero fields. At this point, the tale gets sordid.
The documentation implies that specifying /vmg is equivalent to declaring every class with the __virtual_inheritance keyword. It isn't. Instead, it uses an even bigger structure which I've called unknown_inheritance. It also uses this whenever it has to make a member function pointer for a class when all it's seen is a forward declaration. They can't use their __virtual_inheritance pointers because they use a really silly optimization. Here's the algorithm they use:
// Microsoft and Intel use this for the 'Unknown' case. // Microsoft also use it when the /vmg option is used // In VC1.5 - VC6, this structure is broken! See below. struct MicrosoftUnknownMFP{ FunctionPointer m_func_address; // 64 bits for Itanium. int m_delta; int m_vtordisp; int m_vtable_index; // or 0 if no virtual inheritance }; if (vindex=0) adjustedthis = this + delta else adjustedthis = this + delta + vtordisp + *(*(this + vtordisp) + vindex) CALL funcadr
In the virtual inheritance case, the vtordisp value is not stored in the __virtual_inheritance pointer! Instead, the compiler hard-codes it into the assembly output when the function is invoked. But to deal with incomplete types, you need to know it. So they ended up with two types of virtual inheritance pointers. But until VC7, the unknown_inheritance case was hopelessly buggy. The vtordisp and vindex fields were always zero! Horrifying consequence: on VC4-VC6, specifying the /vmg option (without /vmm or /vms) can result in the wrong function being called! This would be extremely difficult to track down. In VC4, the IDE had a box for selecting the /vmg option, but it was disabled. I suspect that someone at MS knew about the bug, but it was never listed in their knowledge base. They finally fixed it in VC7.
Intel uses the same calculation as MSVC, but their /vmg option behaves quite differently (it has almost no effect - it only affects the unknown_inheritance case). The release notes for their compiler state that conversions between pointer to member types are not fully supported in the virtual inheritance case, and warns that compiler crashes or incorrect code generation may result if you try. This is a very nasty corner of the language.
And then there's CodePlay. Early versions of Codeplay's VectorC had options for link compatibility with Microsoft VC6, GNU, and Metrowerks. But, they always used the Microsoft method. They reverse-engineered it, just as I have, but they didn't detect the unknown_inheritance case, or the vtordisp value. Their calculations implicitly (and incorrectly) assumed vtordisp=0, so the wrong function could be called in some (obscure) cases. But Codeplay's upcoming release of VectorC 2.2.1 has fixed these problems. The member function pointers are now binary compatible with either Microsoft or GNU. With some high powered optimisations and a massive improvement in standards conformance (partial template specialisation, etc), this is becoming a very impressive compiler.
In theory, all of these vendors could radically change their technique for representing MFPs. In practice, this is extremely unlikely, because it would break a lot of existing code. At MSDN, there is a very old article that was published by Microsoft which explains the run-time implementation details of Visual C++ [JanGray]. It's written by Jan Gray, who actually wrote the MS C++ object model in 1990. Although the article dates from 1994, it is still relevant - excluding the bug fix, Microsoft hasn't changed it for 15 years. Similarly, the earliest compiler I have (Borland C++ 3.0, (1990)) generates identical code to Borland's most recent compiler, except of course that 16 bit registers are replaced with 32 bit ones.
By now, you know far too much about member function pointers. What's the point? I've dragged you through this to establish a rule. Although these implementations are very different from one another, they have something useful in common: the assembly code required to invoke a member function pointer is identical, regardless of what class and parameters are involved. Some compilers apply optimizations depending on the inheritance nature of the class, but when the class being invoked is of incomplete type, all such optimizations are impossible. This fact can be exploited to create efficient delegates.
Unlike member function pointers, it's not hard to find uses for delegates. They can be used anywhere you'd use a function pointer in a C program. Perhaps most importantly, it's very easy to implement an improved version of the Subject/Observer design pattern [GoF, p. 293] using delegates. The Observer pattern is most obviously applicable in GUI code, but I've found that it gives even greater benefits in the heart of an application. Delegates also allow elegant implementations of the Strategy [GoF, p. 315] and State [GoF, p. 305] patterns.
Now, here's the scandal. Delegates aren't just far more useful than member function pointers. They are much simpler as well! Since delegates are provided by the .NET languages, you might imagine that they are a high-level concept that is not easily implemented in assembly code. This is emphatically not the case: invoking a delegate is intrinsically a very low-level concept, and can be as low-level (and fast) as an ordinary function call. A C++ delegate just needs to contain a this pointer and a simple function pointer. When you set a delegate, you provide it with the this pointer at the same time that you specify the function to be called. The compiler can work out how the this pointer needs to be adjusted at the time that the delegate is set. There's no work to be done when invoking the delegate. Even better, the compiler can frequently do all the work at compile time, so that even setting the delegate is a trivial operation. The assembly code produced by invoking a delegate on an x86 system should be as simple as:
mov ecx, [this] call [pfunc]
However, there's no way to generate such efficient code in standard C++. Borland solves this problem by adding a new keyword (__closure) to their C++ compiler, allowing them to use convenient syntax and generate optimal code. The GNU compiler also adds a language extension, but it is incompatible with Borland's. If you use either of these language extensions, you restrict yourself to a single compiler vendor. If instead, you constrain yourself to standard C++, it's still possible to implement delegates, they are just not as efficient.
Interestingly, in C# and other .NET languages, a delegate is apparently dozens of times slower than a function call (MSDN). I suspect that this is because of the garbage collection and the .NET security requirements. Recently, Microsoft added a "unified event model" to Visual C++, with the keywords __event, __raise, __hook, __unhook, event_source, and event_receiver. Frankly, I think this feature is appalling. It's completely non-standard, the syntax is ugly and doesn't even look like C++, and it generates very inefficient code.
There is a plethora of implementations of delegates using standard C++. All of them use the same idea. The basic observation is that member function pointers act as delegates -- but they only work for a single class. To avoid this limitation, you add another level of indirection: you can use templates to create a 'member function invoker' for each class. The delegate holds the this pointer, and a pointer to the invoker. The member function invoker needs to be allocated on the heap.
There are many implementations of this scheme, including several here at CodeProject. They vary in their complexity, their syntax (especially, how similar their syntax is to C#), and in their generality. The definitive implementation is boost::function. Recently, it was adopted into the next version of the C++ standard [Sutter1]. Expect its use to become widespread.
As clever as the traditional implementations are, I find them unsatisfying. Although they provide the desired functionality, they tend to obscure the underlying issue: a low-level construct is missing from the language. It's frustrating that on all platforms, the 'member function invoker' code will be identical for almost all classes. More importantly, the heap is used. For some applications, this is unacceptable.
One of my projects is a discrete event simulator. The core of such a program is an event dispatcher, which calls member functions of the various objects being simulated. Most of these member functions are very simple: they just update the internal state of the object, and sometimes add future events to the event queue. This is a perfect situation to use delegates. However, each delegate is only ever invoked once. Initially, I used boost::function, but I found that the memory allocation for the delegates was consuming over a third of the entire program running time! I wanted real delegates. For crying out loud, it should be just two ASM instructions!
I don't always (often?) get what I want, but this time I was lucky. The C++ code I present here generates optimal assembly code in almost all circumstances. Most importantly, invoking a single-target delegate is as fast as a normal function call. There is no overhead whatsoever. The only downside is that, to achieve this, I had to step outside the rules of standard C++. I used the clandestine knowledge of member function pointers to get this to work. Efficient delegates are possible on any C++ compiler, if you are very careful, and if you don't mind some compiler-specific code in a few cases.
The core of my code is a class which converts an arbitrary class pointer and arbitrary member function pointer into a generic class pointer and a generic member function. C++ doesn't have a 'generic member function' type, so I cast to member functions of an undefined CGenericClass.
Most compilers treat all member function pointers identically, regardless of the class. For most of them, a straightforward reinterpret_cast<> from the given member function pointer to the generic member function pointer would work. In fact, if this doesn't work, the compiler is non-standard. For the remaining compilers (Microsoft Visual C++ and Intel C++), we have to transform multiple- or virtual-inheritance member function pointers into single-inheritance pointers. This requires some template magic and a horrible hack. Note that the hack is only necessary because these compilers are not standards-compliant, but there is a nice reward: the hack gives optimal code.
Since we know how the compiler stores member function pointers internally, and because we know how the this pointer needs to be adjusted for the function in question, we can adjust the this pointer ourselves when we are setting the delegate. For single inheritance pointers, no adjustment is required; for multiple inheritance, there's a simple addition; and for virtual inheritance ... it's a mess. But it works, and in most cases, all of the work is done at compile time!
How can we distinguish between the different inheritance types? There's no official way to find out whether a class used multiple inheritance or not. But there's a sneaky way, which you can see if you look at the table I presented earlier -- on MSVC, each inheritance style produces a member function pointer with a different size. So, we use template specialization based on the size of the member function pointer! For multiple inheritance, it's a trivial calculation. A similar, but much nastier calculation is used in the unknown_inheritance (16 byte) case.
For Microsoft's (and Intel's) ugly, non-standard 12 byte virtual_inheritance pointers, yet another trick is used, based on an idea invented by John Dlugosz. The crucial feature of Microsoft/Intel MFPs which we exploit is that the CODEPTR member is always called, regardless of the values of the other members. (This is not true for other compilers, e.g., GCC, which obtain the function address from the vtable if a virtual function is being called.) Dlugosz's trick is to make a fake member function pointer, in which the codeptr points to a probe function which returns the 'this' pointer that was used. When you call this function, the compiler does all the calculation work for you, making use of the secretive vtordisp value.
Once you can cast any class pointer and member function pointer into a standard form, it's easy (albeit tedious) to implement single-target delegates. You just need to make template classes for all of the different numbers of parameters.
A very significant additional benefit of implementing delegates by this non-standard cast is that they can be compared for equality. Most existing delegate implementations can't do this, and this makes it difficult to use them for certain tasks, such as implementing multi-cast delegates [Sutter3].
Ideally, a simple non-member function, or a static member function, could be used as a delegate target. This can be achieved by converting the static function into a member function. I can think of two methods of doing this, in both of which the delegate points to an 'invoker' member function which calls the static function.
The Evil method uses a hack. You can store the function pointer instead of the this pointer, so that when the invoker function is called, it just needs to cast this into a static function pointer and call that. The nice thing about this is that it has absolutely no effect on the code for normal member functions. The problem with it is that it is a hack as it requires casting between code and data pointers. It won't work on systems where code pointers are larger than data pointers (DOS compilers using the medium memory model). It will work on all 32 and 64 bit processors that I know of. But because it's Evil, we need an alternative.
The Safe method is to store the function pointer as an extra member of the delegate. The delegate points to its own member function. Whenever the delegate is copied, these self-references must be transformed, and this complicates the = and == operators. This increases the size of the delegate by four bytes, and increases the complexity of the code, but it has no effect on the invocation speed.
I've implemented both methods, because both have merit: the Safe method is guaranteed to work, and the Evil method generates the same ASM code that a compiler would probably generate if it had native support for delegates. The Evil method can be enabled with a #define (FASTDELEGATE_USESTATICFUNCTIONHACK).
Footnote: Why does the evil method work at all? If you look closely at the algorithm that is used by each compiler when invoking a member function pointer, you can see that for all those compilers, when a non-virtual function is used with single inheritance (ie delta=vtordisp=vindex=0), the instance pointer doesn't enter into the calculation of what function to call. So, even with a garbage instance pointer, the correct function will be called. Inside that function, the this pointer that is received will be garbage + delta = garbage. (To put it another way -- garbage in, unmodified garbage out!) And at that point, we can convert our garbage back into a function pointer. This method would not work if the "static function invoker" was a virtual function.
garbage + delta = garbage
The source code consists of the FastDelegate implementation (FastDelegate.h), and a demo .cpp file to illustrate the syntax. To use with MSVC, create a blank console app, and add these two files to it. For GNU, just type "g++ demo.cpp" on the command line.
g++ demo.cpp
The fast delegates will work with any combination of parameters, but to make it work on as many compilers as possible, you have to specify the number of parameters when declaring the delegate. There is a maximum of eight parameters, but it's trivial to increase this limit. The namespace fastdelegate is used. All of the messiness is in an inner namespace called detail.
Fastdelegates can be bound to a member function or a static (free) function, using the constructor or bind(). They default to 0 (null). They can also be set to null with clear(). They can be tested for null using operator ! or empty().
Unlike most other implementations of delegates, equality operators (==, !=) are provided. They work even when inline functions are involved.
Here's an excerpt from FastDelegateDemo.cpp which shows most of the allowed operations. CBaseClass is a virtual base class of CDerivedClass. A flashy example could easily be devised; this is just to illustrate the syntax.
using namespace fastdelegate; int main(void) { // Delegates with up to 8 parameters are supported. // Here's the case for a void function. // We declare a delegate and attach it to SimpleVoidFunction() printf("-- FastDelegate demo --\nA no-parameter delegate is declared using FastDelegate0\n\n"); FastDelegate0 noparameterdelegate(&SimpleVoidFunction); noparameterdelegate(); // invoke the delegate - this calls SimpleVoidFunction() printf("\n-- Examples using two-parameter delegates (int, char *) --\n\n"); typedef FastDelegate2<int, char *> MyDelegate; MyDelegate funclist[10]; // delegates are initialized to empty CBaseClass a("Base A"); CBaseClass b("Base B"); CDerivedClass d; CDerivedClass c; // Binding a simple member function funclist[0].bind(&a, &CBaseClass::SimpleMemberFunction); // You can also bind static (free) functions funclist[1].bind(&SimpleStaticFunction); // and static member functions funclist[2].bind(&CBaseClass::StaticMemberFunction); // and const member functions funclist[3].bind(&a, &CBaseClass::ConstMemberFunction); // and virtual member functions. funclist[4].bind(&b, &CBaseClass::SimpleVirtualFunction); // You can also use the = operator. For static functions, // a fastdelegate looks identical to a simple function pointer. funclist[5] = &CBaseClass::StaticMemberFunction; // The weird rule about the class of derived // member function pointers is avoided. // Note that as well as .bind(), you can also use the // MakeDelegate() global function. funclist[6] = MakeDelegate(&d, &CBaseClass::SimpleVirtualFunction); // The worst case is an abstract virtual function of a // virtually-derived class with at least one non-virtual base class. // This is a VERY obscure situation, which you're unlikely to encounter // in the real world, but it's included as an extreme test. funclist[7].bind(&c, &CDerivedClass::TrickyVirtualFunction); // ...BUT in such cases you should be using the base class as an // interface, anyway. The next line calls exactly the same function. funclist[8].bind(&c, &COtherClass::TrickyVirtualFunction); // You can also bind directly using the constructor MyDelegate dg(&b, &CBaseClass::SimpleVirtualFunction); char *msg = "Looking for equal delegate"; for (int i=0; i<10; i++) { printf("%d :", i); // The ==, !=, <=,<,>, and >= operators are provided // Note that they work even for inline functions. if (funclist[i]==dg) { msg = "Found equal delegate"; }; // There are several ways to test for an empty delegate // You can use if (funclist[i]) // or if (!funclist.empty()) // or if (funclist[i]!=0) // or if (!!funclist[i]) if (funclist[i]) { // Invocation generates optimal assembly code. funclist[i](i, msg); } else { printf("Delegate is empty\n"); }; } };
Version 1.3 of the code adds the ability to have non-void return values. Like std::unary_function, the return type is the last parameter. It defaults to void, which preserves backwards compatibility, and also means that the most common case remains simple. I wanted to do this without losing performance on any platform. It turned out to be easy to do this for any compiler except MSVC6. There are two significant limitations of VC6:
I've got around it with two tricks:
const void *
There is one breaking change: all instances of FastDelegate0 must be changed to FastDelegate0<>. This change can be performed with a global search-and-replace through all your files, so I believe it should not be too onerous. I believe this change leads to more intuitive syntax: the declaration of any kind of void FastDelegate is now the same as a function declaration, except that () is replaced with <>. If this change really annoys anyone, you can modify the header file: wrap the FastDelegate0<> definition inside a separate namespace newstyle { and } typedef newstyle::FastDelegate0<> FastDelegate0;. You would need to change the corresponding MakeDelegate function too.
void FastDelegate
namespace newstyle {
} typedef newstyle::FastDelegate0<> FastDelegate0;
The MakeDelegate template allows you to use a FastDelegate as a drop-in replacement for a function pointer. A typical application is to have a FastDelegate as a private member of a class and use a modifier function to set it (like a Microsoft __event). For example:
// Accepts any function with a signature like: int func(double, double); class A { public: typedef FastDelegate2<double, double, int> FunctionA; void setFunction(FunctionA somefunc){ m_HiddenDelegate = somefunc; } private: FunctionA m_HiddenDelegate; }; // To set the delegate, the syntax is: A a; a.setFunction( MakeDelegate(&someClass, &someMember) ); // for member functions, or a.setFunction( &somefreefunction ); // for a non-class or static function
Jody Hagins has enhanced the FastDelegateN classes to allow the same attractive syntax provided by recent versions of Boost.Function and Boost.Signal. On compilers with partial template specialization, you have the option of writing FastDelegate< int (char *, double)> instead of FastDelegate2<char *, double, int>. Fantastic work, Jody! If your code needs to compile on VC6, VC7.0, or Borland, you need to use the old, portable syntax. I've made changes to ensure that the old and new syntax are 100% equivalent and can be used interchangeably.
FastDelegate< int (char *, double)>
FastDelegate2<char *, double, int>
Jody also contributed a helper function, bind, to allow code written for Boost.Function and Boost.Bind to be rapidly converted to FastDelegates. This allows you to quickly determine how much the performance of your existing code would improve if you switched to FastDelegates. It can be found in "FastDelegateBind.h". If we have the code:
using boost::bind; bind(&Foo:func, &foo, _1, _2);
we should be able to replace the "using" with using fastdelegate::bind and everything should work fine. Warning: The arguments to bind are ignored! No actual binding is performed. The behavior is equivalent to boost::bind only in the trivial (but most common) case where only the basic placeholder arguments _1, _2, _3, etc. are used. A future release may support boost::bind properly.
using fastdelegate::bind
_1, _2, _3,
FastDelegates of the same type can now be compared with <, >, <=, >=. Member function pointers don't support these operators, but they can be emulated with a simple binary comparison using memcmp(). The resulting strict weak ordering is physically meaningless, and is compiler-dependent, but it allows them to be stored in ordered containers like std:set.
A new class, DelegateMemento, is provided to allow disparate collections of delegates. Two extra members have been added to each FastDelegate class:
const DelegateMemento GetMemento() const; void SetMemento(const DelegateMemento mem);
DelegegateMementos can be copied and compared to one another (==, !=, >, <, >=, <=), allowing them to be stored in any ordered or unordered container. They can be used as a replacement for a union of function pointers in C. As with a union of disparate types, it is your responsibility to ensure that you are using the same type consistently. For example, if you get a DelegateMemento from a FastDelegate2 and save it into a FastDelegate3, your program will probably crash at runtime when you invoke it. In the future, I may add a debug mode which uses the typeid operator to enforce type safety. DelegateMementos are intended primarily for use in other libraries, rather than in general user code. An important usage is Windows messaging, where a dynamic std::map<MESSAGE, DelegateMemento> can replace the static message maps found in MFC and WTL. But that's another article.
std::map<MESSAGE, DelegateMemento>
You can now use the if (dg) {...} syntax (where dg is a fast delegate) as an alternative to if (!dg.empty()), if (dg!=0) or even the ugly but efficient if (!!dg). If you're just using the code, all you need to know is that it works correctly on all compilers, and it does not inadvertently allow other operations.
if (dg) {...}
if (!dg.empty())
if (dg!=0)
if (!!dg)
The implementation was more difficult than expected. Merely supplying an operator bool is dangerous because it lets you write things like int a = dg; when you probably meant int a = dg();. The solution is to use the Safe Bool idiom [Karlsson]: a conversion to a private member data pointer is used instead of bool. Unfortunately, the usual Safe Bool implementation mucks up the if (dg==0) syntax, and some compilers have bugs in their implementations of member data pointers (hmm, another article?), so I had to develop a couple of tricks. One method which others have used in the past is to allow comparisons with integers, and ASSERT if the integer is non-zero. Instead, I use a more verbose method. The only side-effect is that comparisons with function pointers are more optimal! Ordered comparisons with the constant 0 are not supported (but it is valid to compare with a function pointer which happens to be null).
operator bool
int a = dg;
int a = dg();
if (dg==0)
The source code attached to this article is released into the public domain. You may use it for any purpose. Frankly, writing the article was about ten times as much work as writing the code. Of course, if you create great software using the code, I would be interested to hear about it. And submissions are always welcome.
Because it relies on behavior that is not defined by the standard, I've been careful to test the code on many compilers. Ironically, it's more portable than a lot of 'standard' code, because most compilers don't fully conform to the standard. It has also become safer through being widely known. The major compiler vendors and several members of the C++ Standards commitee know about the techniques presented here (in many cases, the lead compiler developers have contacted me about the article). There is negligible risk that vendors will make a change that would irreparably break the code. For example, no changes were required to support Microsoft's first 64 bit compilers. Codeplay has even used FastDelegates for internal testing of their VectorC compiler (it's not quite an endorsement, but very close).
The FastDelegate implementation has been tested on Windows, DOS, Solaris, BSD, and several flavors of Linux, using x86, AMD64, Itanium, SPARC, MIPS, .NET virtual machines, and some embedded processors. The following compilers have been tested successfully:
Here is the status of all other C++ compilers that I know of which are still in use:
And yet some people are still complaining that the code is not portable! (Sigh).
What started as an explanation of a few lines of code I'd written has turned into a monstrous tutorial on the perils of an obscure part of the language. I also discovered previously unreported bugs and incompatibilities in six popular compilers. It's an awful lot of work for two lines of assembly code!
I hope that I've cleared up some of the misconceptions about the murky world of member function pointers and delegates. We've seen that much of the weirdness of member function pointers arise because they are implemented very differently by various compilers. We've also seen that, contrary to popular opinion, delegates are not a complicated, high-level construct, but are in fact very simple. I hope that I've convinced you that they should be part of the language. There is a reasonable chance that some form of direct compiler support for delegates will be added to C++ when the C++0x standard is released. (Start lobbying the Standards committee!)
To my knowledge, no previous implementation of delegates in C++ is as efficient or easy to use as the FastDelegates I've presented here. It may amuse you to learn that most of it was programmed one-handed while I tried to get my baby daughter to sleep... I hope you find it useful.
I've looked at dozens of websites while researching this article. Here are a few of the most interesting ones:
operator ->*
if (dg)
This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)
<br /> class EventConsumer<br /> {<br /> private:<br /> struct EventReceiver;<br /> friend EventReceiver;<br /> std::auto_ptr<EventReceiver> receiver;<br /> };<br /> <br /> // .cpp<br /> struct EventConsumer::EventReceiver : ICallbackInterface<br /> {<br /> virtual void onEvent1()<br /> {<br /> // ....<br /> }<br /> <br /> virtual void onEvent2()<br /> {<br /> // ....<br /> }<br /> };<br />
<br /> #include <srutil/event/event.hpp> // from my article<br /> #include <iostream><br /> <br /> //************** helpers (candidates for reusing) ******************<br /> <br /> // provides common functioality of event receivers<br /> template <class TCallbackInterface, class TOwnerType><br /> struct GeneralizedEventReceiver : TCallbackInterface<br /> {<br /> public:<br /> typedef TCallbackInterface interface_type;<br /> typedef TOwnerType owner_type;<br /> typedef GeneralizedEventReceiver receiver_type;<br /> <br /> GeneralizedEventReceiver() : that() {}<br /> void bind(srutil::event_source<TCallbackInterface*> const& source, TOwnerType* that)<br /> {<br /> this->that = that;<br /> binder.bind(source, this);<br /> }<br /> <br /> protected:<br /> TOwnerType * that; // usually event recievers need access to owner object<br /> private:<br /> srutil::event_binder<TCallbackInterface*> binder;<br /> };<br /> <br /> // boost::bind may be used instead it (just to reduce dependences in the example)<br /> template <class TCallbackInterface, typename R><br /> struct method_invoker0<br /> {<br /> typedef R (TCallbackInterface::*method_type)();<br /> method_type method;<br /> <br /> method_invoker0(method_type method) : method(method) {}<br /> <br /> R operator()(TCallbackInterface* receiver) const<br /> {<br /> return (receiver->*method)();<br /> }<br /> };<br /> <br /> // allows to simplify an emiting code; may be overloaded for any numbers of arguments<br /> template <class TCallbackInterface, typename R><br /> void emit_event(srutil::event_source<TCallbackInterface*> & source, R (TCallbackInterface::*method)())<br /> {<br /> source.emit(method_invoker0<TCallbackInterface, R>(method));<br /> }<br /> <br /> //************** example code ******************<br /> class EventProducer<br /> {<br /> public:<br /> struct ICallbackInterface;<br /> srutil::event_source<ICallbackInterface*> const& getEventSource() const {return eventSource;}<br /> <br /> void test();<br /> <br /> private:<br /> srutil::event_source<ICallbackInterface*> eventSource;<br /> };<br /> <br /> struct EventProducer::ICallbackInterface<br /> {<br /> virtual void onEvent1() = 0;<br /> virtual void onEvent2() = 0;<br /> virtual void onEvent3() = 0;<br /> virtual void onEvent4() = 0;<br /> };<br /> <br /> class EventConsumer<br /> {<br /> public:<br /> EventConsumer(EventProducer* producer)<br /> {<br /> eventReceiver.bind(producer->getEventSource(), this);<br /> };<br /> <br /> private:<br /> struct EventReceiver : GeneralizedEventReceiver<EventProducer::ICallbackInterface, EventConsumer><br /> {<br /> virtual void onEvent1();<br /> virtual void onEvent2();<br /> virtual void onEvent3();<br /> virtual void onEvent4();<br /> } eventReceiver;<br /> friend struct EventReceiver;<br /> };<br /> <br /> void EventConsumer::EventReceiver::onEvent1()<br /> {<br /> std::cout << that << " has recieved Event1.\n";<br /> }<br /> <br /> void EventConsumer::EventReceiver::onEvent2()<br /> {<br /> std::cout << that << " has recieved Event2.\n";<br /> }<br /> <br /> void EventConsumer::EventReceiver::onEvent3()<br /> {<br /> std::cout << that << " has recieved Event3.\n";<br /> }<br /> <br /> void EventConsumer::EventReceiver::onEvent4()<br /> {<br /> std::cout << that << " has recieved Event4.\n";<br /> }<br /> <br /> void EventProducer::test()<br /> {<br /> emit_event(eventSource, &ICallbackInterface::onEvent1);<br /> emit_event(eventSource, &ICallbackInterface::onEvent2);<br /> emit_event(eventSource, &ICallbackInterface::onEvent3);<br /> emit_event(eventSource, &ICallbackInterface::onEvent4);<br /> }<br /> <br /> int main()<br /> {<br /> EventProducer producer;<br /> EventConsumer consumer1(&producer);<br /> EventConsumer consumer2(&producer);<br /> <br /> producer.test();<br /> <br /> return 0;<br /> }<br />
<br /> typedef void (*method_type)();<br /> <br /> struct DECL_SPEC A<br /> {<br /> static void method() {}<br /> };<br /> <br /> struct B<br /> {<br /> static void method() {}<br /> };<br /> <br /> DECL_SPEC method_type get_a_address();<br /> DECL_SPEC method_type get_b_address();<br />
<br /> #define DECL_SPEC __declspec(dllexport)<br /> #include "dll.h"<br /> <br /> method_type get_a_address()<br /> {<br /> return &A::method;<br /> }<br /> <br /> method_type get_b_address()<br /> {<br /> return &B::method;<br /> }<br />
<br /> #include <stdio.h><br /> #define DECL_SPEC __declspec(dllimport)<br /> #include "dll/dll.h"<br /> <br /> method_type get_a_address_int()<br /> {<br /> return &A::method;<br /> }<br /> <br /> method_type get_b_address_int()<br /> {<br /> return &B::method;<br /> }<br /> <br /> int main()<br /> {<br /> printf("%p\r\n", get_a_address());<br /> printf("%p\r\n", get_a_address_int());<br /> printf("%p\r\n", get_b_address());<br /> printf("%p\r\n", get_b_address_int());<br /> return 0;<br /> }<br />
<br /> #include "FastDelegate.h"<br /> #include <stdio.h><br /> using namespace fastdelegate;<br /> <br /> class TestClass<br /> {<br /> public:<br /> void method1() {}<br /> void method2() {}<br /> };<br /> <br /> int main()<br /> {<br /> TestClass inst;<br /> fastdelegate::FastDelegate0<void> d1 = MakeDelegate(&inst, &TestClass::method1);<br /> fastdelegate::FastDelegate0<void> d2 = MakeDelegate(&inst, &TestClass::method2);<br /> <br /> printf("Comparation result: %s\n", d1 != d2 ? "ok" : "surprise!");<br /> return 0;<br /> }<br />
Comparation result: surprise!
void func(int, char *)
template <class P1, class P2> class VoidMulticastDelegate2 { typedef FastDelegate2< P1, P2> BaseDelegate; typedef std::set<BaseDelegate> Container; Container m_list; typedef FastDelegate1< Retval > InvokerDelegate; InvokerDelegate m_invoker; public: void SetInvoker( void operator +=(BaseDelegate dg) { m_list.insert(dg); } void operator -=(BaseDelegate dg) { m_list.erase(dg); } void operator()(P1 p1, P2 p2) { for (Container::iterator it=m_list.begin(); it!=m_list.end(); ++it) { (*it)(p1, p2); } } }; int main() { CleverClass clever; VoidMulticastDelegate2<int, char*> multi; multi +=&freefunc; multi +=MakeDelegate(&clever, &CleverClass::SomethingSpecial); multi(6, " is a perfect number"); multi -=&freefunc; multi(7, " is a prime"); }
FastDelegate0<> noparameterdelegate(&SimpleVoidFunction);
FastDelegate<void ()> noparameterdelegate;<br /> noparameterdelegate = &SimpleVoidFunction;
noparameterdelegate = 0;
Demo.cpp: In function `int main()':<br /> Demo.cpp:67: error: ambiguous overload for 'operator=' in 'noparameterdelegate = SimpleVoidFunction'<br /> FastDelegate.h:1669: note: candidates are: void fastdelegate::FastDelegate<R ()()>::operator=(const fastdelegate::FastDelegate0<R>&) [with R = void]<br /> FastDelegate.h:1634: note: fastdelegate::FastDelegate<void ()()>& fastdelegate::FastDelegate<void ()()>::operator=(const fastdelegate::FastDelegate<void ()()>&)
General News Suggestion Question Bug Answer Joke Praise Rant Admin
Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.


text:
Need a personal trainer?
1. Fill in the request
Qjob specialists get informed about new tasks immediately
2. Get quotes
Get quotes. Interested specialists will send you a quote for their services.
3. Choose a specialist
Compare incoming quotes, find out more about the specialists after browsing their profile page and choose the one that is the best for you!
We notify relevant specialists of new tasks. Usually, clients receive 3-5 quotes from specialists, which you can view on the page «My Tasks». The first proposals will come in 5-10 minutes after the publication of the task. We do not show your contact details to specialists, so you must check who applied to your task and either contact them on the provided channels or by using «Chat».

subset: commoncrawl


text: Join Donate Resources Radio Show Archives Shop. Connect. Support. Thrive.Moms & Dads have redefined the small business world and used it to build a better future for their families. You can make a conscious decision to support your community's economy by purchasing their products & services. Win-win. Search for Near Search {"hide_search_input":"","hide_near_input":"","input_size":"","bar_flex_wrap":"","bar_flex_wrap_md":"","bar_flex_wrap_lg":"","input_border":"","input_border_opacity":"","input_rounded_size":"","btn_bg":"","btn_rounded_size":"","btn_rounded_size_md":"","btn_rounded_size_lg":"","bg":"","mt":"","mr":"","mb":"3","ml":"","pt":"","pr":"","pb":"","pl":"","border":"","rounded":"","rounded_size":"","rounded_size_md":"","rounded_size_lg":"","shadow":"","css_class":""} Apparel/ Accessories Arts & Crafts Home Design/ Decor Entertainment Family Services Home Services Childcare/ Education Personal Development Business Services Beauty/ Wellness Gifts Travel Newest Sort Options NewestRating Default View: Grid 1 View: Grid 2 View: Grid 3 View: Grid 4 View: Grid 5 View: List Talk Fusion -Video E-mail PLUS MORE Loading... No Records Found Sorry, no records were found. Please adjust your search criteria and try again. Maps failed to load Sorry, unable to load the Maps API.


text:
Patent ductus arteriosus (PDA) is a heart defect found in the days or weeks after birth. The ductus arteriosus is a normal blood vessel that's part of fetal blood circulation before a baby is born. It's an extra blood vessel that connects 2 arteries: the pulmonary artery and the aorta. The pulmonary artery carries blood from the heart to the lungs. The aorta carries blood from the heart to the body. Before birth, the ductus arteriosus lets blood go around (bypass) the lungs. This is because the baby gets oxygen from the mother through the placenta.
All babies are born with this opening between the aorta and the pulmonary artery. But it often closes on its own shortly after birth, once the baby breathes on their own and inflates their lungs. If it stays open (patent), it's called patent ductus arteriosus. With PDA, extra blood flows to the lungs. If the PDA is large, too much blood goes to the lungs. The blood vessels and the lungs have to work much harder to handle the extra blood. This can lead to fluid buildup in the lungs. The baby can have a harder time breathing and feeding.
PDA occurs twice as often in girls as in boys.
Experts don't know exactly why PDA occurs. It's more common in babies born prematurely. PDA can also occur along with other heart defects.
The size of the opening between the aorta and the pulmonary artery will affect symptoms. If your baby has a small opening, they may not have symptoms. If your baby has a larger opening, they may have symptoms. These are the most common symptoms of PDA:
Skin that turns a blue color from not getting enough oxygen (cyanosis)
Very tired
Fast or hard breathing
Trouble feeding, or tiredness while feeding
Poor weight gain
In older children, trouble doing activities
The symptoms of PDA can seem like other health conditions. Have your child see their healthcare provider for a diagnosis.
The healthcare provider will ask about your baby's symptoms and health history. They will give your baby a physical exam. The provider may find a heart murmur or other symptoms during an exam. The provider may refer your baby to a pediatric cardiologist. This is a healthcare provider with special training to diagnose and treat heart problems in children.
The cardiologist will also check your baby and listen to the heart and lungs. The details about the heart murmur will help the provider make the diagnosis. Your baby may need tests, such as:
Echocardiogram (echo). An echo uses sound waves to make a moving picture of the heart and heart valves. An echo shows the blood flow pattern through the PDA. It also shows how large the opening is and how much blood is passing through it. An echo is the most common way that a PDA is diagnosed.
Chest X-ray. A chest X-ray may show an enlarged heart and lung changes in a baby with PDA.
Treatment will depend on your child's symptoms, age, and general health. It will also depend on how severe the condition is.
A small PDA will often close on its own as your child grows. A PDA that causes symptoms will need to be treated with medicine, cardiac catheterization, or surgery. The cardiologist will check from time to time to see if the PDA is closing on its own. If a PDA does not close, it will be fixed to prevent lung problems. Treatment may include the following.
Your baby may need medicines to help the heart work better.
In premature infants, the medicine indomethacin may help close the PDA. It's given through an IV (intravenous) line. Indomethacin stimulates the muscles inside the PDA to tighten. This closes the connection. Your child's cardiologist can answer any questions you may have about this treatment.
Some babies may need medicine to help the heart and lungs work better. Sometimes a baby may need medicine such as diuretics (water pills). Diuretics help the kidneys remove extra fluid from the body. This may be needed when the heart is not working well. Or it may be needed if the blood vessels in the lungs have to make room for more blood flow, as with a PDA.
Most infants with PDA eat and grow normally. Some premature infants or those infants with large PDAs may get tired when feeding. They may not be able to eat enough to gain weight. Nutrition choices include:
High-calorie supplements. Special nutritional supplements may be added to formula or pumped breastmilk to increase the number of calories. Your baby can drink less and still have enough calories to grow correctly.
Supplemental tube feedings. Supplemental feedings are given through a small, flexible tube. The tube passes through the nose or mouth, down the food pipe (esophagus), and into the stomach. The feedings can either be added to or take the place of bottle-feedings. Infants who can drink part of their bottles, but not all, may be fed the rest through the feeding tube. Babies who are too tired to bottle-feed may get all their formula or breastmilk through the feeding tube.
For this test, your baby will be given medicine to relax (sedation). The healthcare provider will put a thin, flexible tube (catheter) into a blood vessel in the groin. They will guide the catheter through the large blood vessel in the groin to the area of the PDA. The catheter will be placed in the PDA. Dye may be injected at this time to help the provider put the catheter in the right place. A coil or closure device, which is attached to the catheter, will then be placed in the PDA. This will stop blood from flowing through the PDA. Once the coil or device is in the correct position, it will be released from the catheter. Then the catheter will be removed.
Surgery can close PDAs. Surgical closure is often advised for babies younger than 6 months who have large defects and symptoms, such as poor weight gain and fast breathing. For babies who don't have symptoms, any surgery may be delayed until after age 6 to 12 months. Your child's cardiologist will advise when the surgery should be done. It is done under general anesthesia so your child will be asleep. Surgery closes the PDA with stitches or clips. This stops the extra blood from getting into the lungs.
If not treated, PDA may lead to long-term lung damage. It can also damage the blood vessels in the lungs. But this is not common because most children will have been treated for their PDA before the lungs and blood vessels get damaged.
If your child is discharged home before having a repair procedure, you will be shown how to feed and give medicine to your child. You will also be taught what symptoms to report to your child's healthcare provider.
When your child is discharged after the PDA repair, you may give them pain medicine such as acetaminophen or ibuprofen to keep them comfortable. Your child's cardiac team will talk about pain control before your child goes home.
Often infants who fed poorly before surgery have more energy once they recover. They begin to eat better and gain weight faster.
Within a few weeks after surgery, older children are often fully recovered and able to do normal activities.
You will get other instructions from your child's cardiac team and the hospital staff.
In premature infants, the outlook after PDA surgical repair depends on gestational age and overall health.
In children born full-term, early diagnosis and repair of PDA lets them live normal, healthy lives. Activity levels, appetite, and growth should return to normal. Your child's cardiologist may advise that your child take antibiotics to prevent infection in the heart lining and valves (bacterial endocarditis).
In children with large PDAs diagnosed very late or never repaired, the outlook is uncertain. They are at risk for increased blood pressure in the blood vessels of the lungs (pulmonary hypertension). These children should get follow-up at a care center that specializes in congenital heart disease.
Talk with your child's cardiologist about your child's outlook.
Call your child's healthcare provider if your child's symptoms get worse or if new symptoms develop, particularly breathing or feeding problems.
PDA is a heart defect found in the days or weeks after birth.
It occurs because a normal fetal connection between the aorta and the pulmonary artery does not close as it should after birth.
PDA happens most often in premature infants. It often occurs with other congenital heart defects.
A small PDA may close on its own as your child grows. If it is large or does not close, your child will need a repair procedure.
An infant or child with PDA will be cared for by a pediatric cardiologist.
Most children with a fixed PDA will live normal, healthy lives.
Tips to help you get the most from a visit to your child's healthcare provider:
Know the reason for the visit and what you want to happen.
Before your visit, write down questions you want answered.
At the visit, write down the name of a new diagnosis and any new medicines, treatments, or tests. Also write down any new instructions your provider gives you for your child.
Know why a new medicine or treatment is prescribed and how it will help your child. Also know what the side effects are.
Ask if your child's condition can be treated in other ways.
Know why a test or procedure is recommended and what the results could mean.
Know what to expect if your child does not take the medicine or have the test or procedure.
If your child has a follow-up appointment, write down the date, time, and purpose for that visit.
Know how you can contact your child's provider after office hours. This is important if your child becomes ill and you have questions or need advice.


text:
The page you requested cannot be found.
The page you are looking for might have been removed, had its name changed, or is temporarily unavailable.
If you are trying to reach a page from a bookmark, the page URL may have changed recently.
Please try the following:
- Open Our Home Page
- Click the back button to in your browser to return to the previous page.
- Enter a term in the search form below.


text:
In 1929, John Matouk founded a company whose mission was to give Americans ready access to the world's most luxurious linens. Mr. Matouk, who was born in Damascus the son of a fine jeweler, understood the principles of meticulous workmanship and good taste. As a young man he immigrated to Italy where he learned the fine linens business, gaining particular expertise in the intricate lace and hand-work that were very much part of the tradition there. He began exporting Italian linens to the United States and he developed a partnership with the outstanding Olga Asta linen and embroidery house located in St. Marks Square in Venice.
In July 1929, he fulfilled his life-long dream to go to the United States. He brought with him trunks of exquisite fabrics and cloths that he sold to the finest stores and elite families. Even in those difficult times there were those who had a passion for fine things and the means to afford them. In fact, in 1933, Mrs. Edsel Ford replenished her linen closets by buying $75,000 of Matouk table linens, an investment of $1.2 million in today's terms.
During World War II, with his supply lines from Europe cut off, Mr. Matouk moved his production to the U.S. He located his factory and offices in Manhattan where they remained until 1985 when his son, George Sr., move the factory to southern New England, home to both a tradition of American textile production and a community of skilled craftspeople.
Over the past eighty years, the Matouk name has become synonymous with John Matouk's uncompromising values: insistence on the highest quality and a passion for luxury. Today John Matouk's grandson, George Matouk Jr., represents the company's third generation of family stewardship. Under his leadership, the company remains committed to designing and manufacturing the world's best-made and best-loved linens for its passionate and discerning clientele around the world.
Call our store at 256-534-4428 to place an order


text:
Catalog Item
Sacramento River Below Keswick Dam Sulfate ug/L Time Series Data
Measurements of Sulfate collected at Sacramento River Below Keswick Dam. Currently collected twice a year, previously collected quarterly. Access further information for this data set by contacting Bureau of Reclamation, California-Great Basin Region, Environmental Affairs Division (CGB-157). See ResultAttributes for STAFF_GAUGE, SMPL_DEPTH, SMPL_CATEGORY_NAME, METHOD_CODE, RESULT_RL, RESULT_RL-UNIT_STD_NAME, RESULT_MDL, RESULT_MDL-UNIT_STD_NAME, USBR_QA_SUBTYPE_NAME, USBR_QULFR_DESCRIPTION. STAFF_GAUGE is the water height in decimal feet measured by gauge (e.g., 15.2). SMPL_DEPTH is the vertical depth at which sample is collected (e.g., 0 - 15 cm). For water samples: depth below water/air interface. For sediment and soil samples: depth below water/solid or air/solid interface. SMPL_CATEGORY_NAME is the category type of sample (e.g., Composite). METHOD_CODE is the name of method used to obtain result (e.g., EPA 200.8). RESULT_RL is the result reporting limit (accounting for dilution) (e.g., 0.02). RESULT_RL-UNIT_STD_NAME is the unit associated with RESULT_RL (e.g., mg/L). RESULT_MDL is the result method detection limit (e.g., 0.007). RESULT_MDL-UNIT_STD_NAME is the unit associated with RESULT_MDL (e.g., mg/L). USBR_QA_SUBTYPE_NAME is the quality control type of the sample (e.g., USBR_BLANK_SPIKE). USBR_QULFR_DESCRIPTION is the quality assurance description (if any) (e.g., Result may have a high bias.).
Catalog Record Title
Sacramento River Below Keswick Dam Water Quality Data from California-Great Basin Baseline Water Quality Monitoring
Generation Effort
California-Great Basin Baseline Water Quality Monitoring
Location Name
Sacramento River below Keswick Dam
Time series
Start Date
Wed Feb 18 1998 13:02:00 GMT-0700 (Mountain Standard Time)
End Date
Tue Oct 23 2018 09:10:00 GMT-0600 (Mountain Daylight Time)
Parameter Name
Parameter Group
Inorganic Analytes
Parameter Transformation
Time Step
Parameter Unit
Item Vertical Datum
Update Frequency
Last Update
Wednesday, June 30th, 2021
Data has been reviewed for accuracy, precision, and contamination. Human and mechanical errors remain possibilities. Please contact the RISE team for further information or questions about this data.


text:
Pecorino Romano, Parmesan, Mozzarella & Ricotta Cheeses.
Ingredients: Pecorino, Ricotta, Parmesan and Mozzarella Cheeses, DellaCasa Pasta (Unbromated and unbleached Semolina Wheat Flour, Eggs, Salt).
Serving Size: 3 to 4 servings
Cooking Time: 4 minutes
Nutrition Facts:
Not surprisingly, her family absolutely loved the simple but tasteful pasta. This success led Luisa to share her new food conception with her friends and colleagues and before long, her pasta developed a dedicated following. Everyone was impressed by the superior quality and taste of Luisa's homemade pasta compared to store-bought commercial pasta. More importantly, they appreciated the fact that making different meals with this pasta is quick and as easy as boiling a pot of water; making it ideal even for those who don't know how to cook or don't have enough free time for cooking.
"Why can't everyone enjoy this truly fresh pasta?" wondered Luisa.
Motivated by this thought, Luisa embarked on a journey to make fresh and delicious pasta available for everyone and thus DellaCasa Pasta was formed. What started out as a way to serve her family nutritious food has now become a fully-fledged unique business, where Luisa and her team work passionately to deliver fresh, authentic pasta products right to you.
With a humble but capable production facility, we continue to expand our operations and grow our retail avenues by attracting people and businesses that cherish delicious and healthy food options. Partnering with like-minded businesses and adding new clients to our ever-growing wholesale portfolio, we take a lot of pride in delivering top quality pasta products to numerous restaurants, hotels and bars.
Even though we are continuously growing and evolving, we have never compromised on our quality standards. You will always feel the care and warmth with which we make our food products.
We don't just say it – we appropriately focus our efforts to ensure that we keep delivering amazing home-made pasta products.


text:
In stock
Discover cost-saving shopping opportunities!
Join now for exclusive member pricing on a wide range of products.
Want to enhance your image and highlight your beauty? Then the Hair Straightener Lovely Style Id Italian 35W Heart will help you to achieve your goals! Enjoy the benefits and advantages of Id Italian products and other hairdressing accessories from 100% original brands.


text:
MOVIE TV TECH GEEKS Principles of Ethical Conduct for journalists and writers includes concepts and language originally developed by the Radio and Television Digital News Association, along with other Movie TV Tech Geeks executives and journalists. These principles are designed to guide journalists working with any news platform, including websites, mobile devices, video, social media channels and live story events.
Journalism must always be accurate, fair and clear so that MTTG readers can trust it. Donors, advertisers, and sponsors never influence our reporting. Articles that are designated at the bottom as being sponsored are our honest opinion as many sponsors have learned.
I. Seeking and reporting the truth in a truthful way
- We will be honest in the way we gather, report and present news – with relevancy, persistence, context, thoroughness, balance, and fairness in mind.
- We will seek to gain understanding of the communities, individuals and issues we cover to provide an informed account of activities.
- We will hold factual information in editorials and other opinion pieces to the same standards of accuracy as news stories.
- We will treat information from unofficial sources, which may include social media, with skepticism and will seek to corroborate information.
- When considering news content created outside of the Network, we will factor the credibility of the source and weigh the value and accuracy of information provided.
II. Serving the public interest
- We will uphold First Amendment principles to serve the democratic process.
- We will be vigilant watchdogs of government and institutions that affect the public, fighting to ensure that the public's business is conducted in public.
- We will seek solutions as well as expose problems and wrongdoing in order to effect change for the good in the communities we serve.
- We will provide public forums for diverse people and views.
- We will reflect and encourage understanding of the diverse segments of our community.
- We will provide editorial and community leadership.
- We will seek to promote understanding of complex issues.
- When sharing editorials and other opinion articles, we will encourage and promote views that foster understanding, insight and civil discourse. We seek to offer viewpoints that represent various views on a particular topic.
- We will consider providing free access to some news coverage during public safety emergencies and as a public service when appropriate, such as elections.
III. Exercising fair play
- We will treat people with respect and compassion.
- We will correct errors promptly.
- We will strive to include all sides relevant to a story. When news develops and we can't include important perspectives immediately, we will share updates, including additional sources, when possible. We also will share attempts to reach sources who add value to the story.
- We will explain to audiences our journalistic processes to promote transparency and engagement.
- We will give particular attention to fairness in relations with people unaccustomed to dealing with the news media.
- We will use confidential sources as the sole basis for published information only as a last resort and under specific procedures that best serve the public's right to know.
IV. Maintaining independence
- We will remain free of outside interests, investments or business relationships that may compromise the credibility of our news reporting.
- We will maintain an impartial, arm's-length relationship with anyone seeking to influence the news.
- We will not support political campaigns or causes through the display of bumper stickers, signs, pins, public/private donations, participation in demonstrations, petitions or in social media posts.
- Individual viewpoints that might cause readers to question our impartiality in news coverage should remain private. This principle does not apply to those who are paid to write and share opinion.
- We will avoid potential conflicts of interest and eliminate inappropriate influence on content.
- We will be free of improper obligations to news sources, newsmakers and advertisers.
- We will not blur the line between advertising and editorial content. We will provide appropriate disclosures, exercise transparency and avoid actual or implicit commercial endorsements by our journalists.
- When sponsorships of news are appropriate, we will not allow them to determine, change or restrict content.
V. Acting with integrity
- We will act honorably and ethically in dealing with news sources, the public and our colleagues.
- We will obey the law.
- We will observe standards of decency.
- We will take responsibility for our decisions and consider the possible consequences of our actions.
- We will be conscientious in observing these principles.
- We will use technological tools with skill and thoughtfulness, avoiding approaches that skew facts, distort reality, or sensationalize events.
- We will not plagiarize or fabricate information.
- We will not alter photos, video or audio to misrepresent events or mislead audiences.


text:
What you need to know if you're upgrading from Windows Phone 7 to 8
This guide is aimed at those who already have a previous generation Windows Phone handset but can also be worthwhile for those of you who are new to the platform.
We're going to cover what you need to know in order to ease the transition from old to new so you can get back to top speed and start enjoying your new device.
When you first switch on your new handset it will talk you through the main bits about signing in with your Microsoft ID. It's really important that you get signed in as soon as possible as it will bring down all your account information, contacts, emails, calendar and some other items.
Where are my apps?
One of the great things about Windows Phone is that if you ever bought an app from the marketplace you won't have to buy it again when you get a replacement device. That same rule applies to Windows Phone 8 devices too. If you bought an app on your old handset you can install it on your new one by browsing the Windows Phone Store to find it and then click "buy". Don't worry though, you won't be buying the app again, the system will then register that you already bought it in the past and ask if you want to install it again.
Get your purchase history and start reinstalling on the windows Phone website
Remembering what apps you bought can be a pain so there are few things you can do to help this process on. Firstly you can head over to www.windowsphone.com and sign in with that Microsoft ID, click on the menu and select 'Purchase History'. From the following page(s) you can reinstall your previous apps from the comfort of your web browser. Best to make sure your phone is connected to Wi-Fi and plugged in and charging while you do that bit.
Backup your old Phone before you forget!
While it's easy to get blinded by the newest thing in the room, make sure you plug in your previous Windows Phone and backup your photos and any music you have there. If you're using a PC, you'll need the easy to use Zune Desktop Client which you can grab here or if you're using an Apple Mac then you'll need the Mac Connector Client which you can grab from here. If it's been a while since you last connected up the phone, you might be surprised at what you'll find.
Get the Windows Central Newsletter
All the latest news, reviews, and guides for Windows and Xbox diehards.
Syncing your content on Windows Phone 8
Things have changed with the latest version of Windows Phone, you'll now have a number of ways to move data back and forth between your computer and your handset.
Windows 8/RT App
Windows 8 Sync App
If you're your running Microsoft's latest and greatest OS, Windows 8 you will need to jump to the App Store and grab the touch friendly WinRT software there. The app will let you automatically import your photos and videos from the phone and of course let you add music, video and photos back to the device.
When adding music you can choose to add songs individually or by just selecting a folder. The app also gives you some shortcuts to browse for apps in the web version of the app store as well as pointing you to www.windowsphone.com which we already covered at the start of this feature. The app is rather light on features at the moment, you may even notice there is no podcast support here we'll tackle that later in the article.
Desktop application - podcast syncing is possible via iTunes.
Windows 7 and Windows 8 Desktop Software
At the moment the desktop version of the syncing tool is probably the best option for the time being as it simply has more functionality. It can even make things easier if you predominantly use iTunes to buy and manage your collection (how things change!). The software works on both Windows 7 and 8 and it runs as a desktop application. As it is a desktop application this means you cannot install and use this if you have a Surface tablet running Windows RT, you'll need to stick to the WinRT app mentioned previously.
With the desktop app you can check to see how the space is being used on your device and can of course import your photos and videos to your PC. The software shows you two views, one of the phones content and the other of the PC's content. If you're looking at the PC content you get to choose to sync things piecemeal or by selecting 'sync all music' it will do the lot. You also get similar options for syncing photos and videos.
What about those podcasts?
In the settings menu of the Windows Phone sync software its likely setup to 'sync music, videos and more' using Windows Libraries. Unfortunately in this mode it currently doesn't understand or recognise podcasts. If you have been using the Zune desktop software in the past to download and manage your podcasts from your PC then that content won't show up at present, we hope this changes rapidly.
The other option in the sync software is to use *gasp* iTunes as the source instead of Windows Libraries. The advantage of this is it gives you the option to manage podcast subscriptions on the iTunes software (which frankly does a better job of it and works globally). With iTunes comes the task of "adding" your music and video to its catalogue, once you have done that (you can just drag and drop your music folder onto iTunes when it's open to kick this off). The content gets indexed by iTunes and will become visible in the Windows Phone syncing software. Your podcasts can now be synced properly to your device.
Desktop App now using iTunes to manage content - happy to see iTunes back?
At present the desktop Windows Phone syncing software is still in 'preview' form so things are bound to change and features will be added. At the moment though, especially if you're keen to keep up to date on your podcasts we recommend using iTunes. If you're in the USA then you can browse and subscribe to podcasts from the Store on your phone. Microsoft have never allowed folks outside the US to subscribe to podcasts using their Store mechanism, we are unable to find out why or even if this will change.
You can now drag and drop content to and from your device
Windows Phone 8 now reveals itself properly in Windows Explorer, when you plug it in to your machine it will simply appear as a storage device under 'Computer', just like a removal disk such as a USB stick or memory card does. You can now simply double click on the phone and add and remove content as you see fit. Just drag and drop things in there, it's really easy. We covered this in depth a while back so we'd urge you to go and take a look. For video syncing and converting the drag and drop method seems to work best at the moment.
Music you have bought from the Zune Marketplace or Xbox Music
Get your previous purchases on your Windows Phone 8 device.
Xbox Music on Windows Phone 8 and the Windows 8 apps now allow you to download your past purchases. On Windows Phone 8 launch Xbox Music, hit settings and ensure that "Xbox Music cloud collection" is enabled. Once you have done that your previous purchases will show up in your music collection. You can then just stream them on your device or if you press and hold you can opt to download the tracks to your phone.
Sounding off
As you can see there are plenty of ways to get your new phone back up and running like you had it before. The syncing software for Windows 8 is in its very early stages and we expect much of this to settle down and get better along the way.
If you have any tips or ideas for getting started or moving your things to your new device then please get in touch and let us know. The comments below are a good place to start but if you have more to say you can drop me a line using the contact form below.


text:
Document Type
University Document
Publication Date
Disclaimer for Student Newspapers
Although this file was scanned from the highest-quality microfilm held by Boise State University, it reveals the limitations of the source microfilm. It is possible to perform a text search of much of this material; however, there are sections where the source microfilm was too faint or unreadable to allow for text scanning. For assistance with this collection of student newspapers, please contact Special Collections and Archives at email@example.com.
Recommended Citation
Students of Boise State University, "Arbiter, March 13" (2006). Student Newspapers. 1874.


text:
Prayer in Distress
1For the leader; with stringed instruments, "upon the eighth."*
A psalm of David.
2Do not reprove me in your anger, LORD,
nor punish me in your wrath.a
3Have pity on me, LORD, for I am weak;
heal me, LORD, for my bones are shuddering.b
4My soul too is shuddering greatly—
5Turn back, LORD, rescue my soul;
save me because of your mercy.
6For in death there is no remembrance of you.
7I am wearied with sighing;
all night long I drench my bed with tears;
I soak my couch with weeping.
8My eyes are dimmed with sorrow,
worn out because of all my foes.e
9Away from me, all who do evil!f
The LORD has heard the sound of my weeping.
10The LORD has heard my plea;
the LORD will receive my prayer.
11My foes will all be disgraced and will shudder greatly;
they will turn back in sudden disgrace.g
* [Psalm 6] The first of the seven Penitential Psalms (Ps 6, 32, 38, 51, 102, 130, 143), a designation dating from the seventh century A.D. for Psalms suitable to express repentance. The psalmist does not, as in many laments, claim to be innocent but appeals to God's mercy (Ps 6:5). Sin here, as often in the Bible, is both the sinful act and its injurious consequences; here it is physical sickness (Ps 6:3–4, 7–8) and the attacks of enemies (Ps 6:8, 9, 11). The psalmist prays that the effects of personal and social sin be taken away.
* [6:1] Upon the eighth: apparently a musical notation, now lost.
* [6:4] How long?: elliptical for "How long will it be before you answer my prayer?" cf. Ps 13:2–3.
* [6:6] A motive for God to preserve the psalmist from death: in the shadowy world of the dead no one offers you praise. Sheol is the biblical term for the underworld where the insubstantial souls of dead human beings dwelt. It was similar to the Hades of Greek and Latin literature. In the second century B.C., biblical books begin to speak positively of life with God after death (Dn 12:1–3; Wis 3).
c. [6:4] Ps 13:2–3; 74:10; 89:47.
d. [6:6] Ps 30:10; 88:11; 115:17; Is 38:18.
e. [6:8] Ps 31:10; 38:11; 40:13.
f. [6:9] Ps 119:115; Mt 7:23; Lk 13:27.
Copyright 2019-2024 USCCB, please review our Privacy Policy