The Task Manager in Chrome is very similar to the Windows Task Manager, in that memory, CPU usage and other activities are monitored. Another similarity is that it can be used to end a process.
There are a couple ways to access the Chrome Task Manager. The easiest way, is the keyboard shortcut (Shift+Esc). Or, it can be accessed by clicking on the wrench icon in the upper right corner, and selecting Tools>Task manager from the menus.
Right clicking on one of the items in the list will bring up a menu, where the information on any checked items will be displayed in columns.
If you want to force a webpage or application to close, just click the End process button.
Advantages of Chrome Task Manager:-
But why would a browser have a Task Manager? Well, Chrome operates a bit differently that other browsers. Instead of occupying one process that takes a huge amount of system memory, Chrome separates tabs as single processes. This is different, yet has some ingenuity to it.
One of the reasons for this is because of security. Being able to lock down each tab as a single process ensures that malware or spyware does not have as much capability to infect the entire browser or system. Another reason is stability. Many of you have probably experienced a crash in Chrome, but that crash only affected a certain tab because it is set up as its own “sandboxed” process.
Even as a browser, Chrome is like an operating system in and of itself. If you look on the bottom left hand side you can see that I have highlighted the “Stats for nerds” link.
Sunday, September 11, 2011
Friday, January 28, 2011
Prefer Pass by Reference Over Pass by Value In C++.
In C, everything is passed by value, and C++ also adopting the pass-by-value convention as its default. The meaning of passing an object by value is defined by the copy constructor of that object's class. So pass-by-value is an extremely expensive operation.
For example:-
class Person {
public:
//Base Class Constructor
Person();
//Base Class Destructor
~Person();
..................//Some code
private:
string p_name, p_address;
};
class Employee: public Person {
public:
//Derived Class Constructor
Employee();
//Base Class Destructor
~Employee();
.................. //Some Code
private:
//Default String Class Object is created
string Dept, Company;
};
Now consider a simple function setEmployee that takes a Employee argument as by value and immediately returns it also as value, plus a call to that function:
Employee setEmployee(Employee s) { return s; }
Employee emp_v; // Employee emp_v is working
Here in above expression, the Employeecopy constructor is called to initialize "s". Then the Employee copy constructor is called again to initialize the object returned by the function with s. Next, the destructor is called for s. Finally, the destructor is called for the object returned by setEmployee(). So the cost of this do-nothing function is two calls to the Employee copy constructor and two calls to the Employee destructor. Also, a Employee object has two string objects within it, so every time you construct a Employee object you must also construct two string objects. A Employee object also inherits from a Person object, so every time you construct a Employee object you must also construct a Person object. A Person object has two additional string objects inside it, so each Person construction also entails two more string constructions. The end result is that passing a Employee object by value leads to one call to the Employee copy constructor, one call to the Person copy constructor, and four calls to the string copy constructor. When the copy of the Employee object is destroyed, each constructor call is matched by a destructor call, so the overall cost of passing a Employee by value is six constructors and six destructors. Because the function setEmployee uses pass-by-value twice (once for the parameter, once for the return value), the complete cost of a call to that function is twelve constructors and twelve destructors!
In fairness to the C++ compiler-writers , this is a worst-case scenario. Compilers are allowed to eliminate some of these calls to copy constructors. To avoid this potentially expensive cost, you need to pass things not by value, but by reference:
const Employee& setEmployee(const Employee& s)
{
return s;
}
This is much more efficient: no constructors or destructors are called, because no new objects are being created. Passing parameters by reference has another advantage: it avoids what is sometimes called the "slicing problem." When a derived class object is passed as a base class object, all the specialized features that make it behave like a derived class object are "sliced" off, and you're left with a simple base class object. This is almost never what you want.
For example, suppose you're working on a set of classes for implementing a Employee management system:
class Person {
public:
string name() const; // return name of Person
virtual void display() const; // draw Person and contents
};
class Employee: public Person {
public:
virtual void display() const;
};
"Display" is virtual function having different definition in both base class and derived class and can be called from another function.
Example:-
// a function that suffers from the slicing problem
void printNameAndDisplay(Person per)
{
cout << per.name(); per.display(); } Consider what happens when you call this function with a Employee object: Employee emp; printNameAndDisplay(emp); As a Person object, and all the specialized information that made "emp" act like a Employee object will be sliced off. Inside printNameAndDisplay, "per" object will always act like an object of class Person, regardless of the type of object that is passed to the function. In particular, the call to display inside printNameAndDisplay will always call Person::display, never Employee::display.
The way around the slicing problem is to pass w by reference:
// a function that doesn't suffer from the slicing problem
void printNameAndDisplay(const Person& per)
{
cout << per.name();
per.display();
}
Now per will act like whatever kind of Person is actually passed in. To emphasize that per isn't modified by this function even though it's passed by reference.
Below are the Three different types of parameter passing can be done :-
A f(A x){ return x;}//two Copy Constructor
A g(A& x){return x;}//single Copy Constructor
A& h(A& x){return x;};//no Copy Constructor
Where A is Class and three functions are f(), g() and h() taking different type of Object as parameter.
Tuesday, January 25, 2011
Name Hidding With Virtual and Normal Base Class Function In C++
In C++, Sometimes ignoring compiler warning leads to a great trouble and create confusion. Below given two sample codes make the difference.
With Static Object :-
1) Override function i.e display() is having same signature in both base and Derived class
class B
{
public:
virtual void display() //Base class function
{ ........ }
};
class D: public B
{
public:
virtual void display()//Derived class function
{ ........ }
};
When Code is compile and executed as below:-
main()
{
D dobj;
dobj.display();//call the Derived class function
}
Here output of the program is normal i.e "dobj.display()" calls derived class display() function.
2) Override function i.e display() is having different signature in both base and Derived class
class B
{
public:
virtual void display(int i) //Base class function
{
.................
}
virtual void display() //Base class function with different signature
{ ................... }
};
class D: public B
{
public:
virtual void display() //Derived class function
{ .................. }
};
Get compiler warning with unexpected output on call of "dobj.display(1)" as mentioned above.
Here all the base class functions are not re-declared in derived class as it has different signature the function declared in the derived class. So the statement "dobj.display(1)", will throw error as the function is not re declared in the Derived class.
Bit Complex Example:-
class Base {
public:
int f() const {
cout << "Base::f()"; return 1; } int f(string) const { return 1; } void g() {} }; class Derived1 : public Base { public: void g() const {} }; class Derived2 : public Base { public: // Redefinition: int f() const { cout << "Derived2::f()\n"; return 2; } }; class Derived3 : public Base { public: // Change return type: void f() const { cout << "Derived3::f()\n"; } }; class Derived4 : public Base { public: // Change argument list: int f(int) const { cout << "Derived4::f()\n"; return 4; } }; main() { string s("hello"); Derived1 d1; int x = d1.f();//Here Both overloaded functions are called as not a single d1.f(s); //overloaded function is re declared in derived class Derived2 d2; x = d2.f(); //! d2.f(s); // string version of the overloaded function is hidden as only one is defined in Derived2 class Derived3 d3; //! x = d3.f(); // Both the overloaded functions are hidden as signature i.e return type is changed in class Derived3 Derived4 d4; //! x = d4.f(); // Both the overloaded functions are hidden as signature i.e argument is changed in class Derived4 x = d4.f(1); } In general, we can say that anytime you redefine an overloaded function name from the base class, all the other versions are automatically hidden in the new class. Same scenario will happen in normal overloaded function i.e if functions are not virtual also. With Dynamic Object :-
Here the same example mentioned in the section (2) will not throw error and do call the base call overloaded function.
class B
{
public:
virtual void display(int i) //Base class function
{ ................. }
virtual void display() //Base class function with different signature
{ ................... }
};
class D: public B
{
public:
virtual void display() //Derived class function
{ ................... }
};
main()
{
B *bptr = new D;
bptr->display(1);//This ll call the Base class overloaded function.
}
Normal behavior happen with pointer pointing to derived class object.
Shallow Copy Vs Deep Copy in C++
A shallow copy means that C++ copies each member of the class individually using the assignment operator. When classes are simple (eg. do not contain any dynamically allocated memory), this works very well.

For example, let’s take a look at our simple class:
class Sample
{
private:
int m_Sample;
public:
Sample(int nSample=0)
{
m_Sample = nSample;
}
};
When C++ does a shallow copy of this class, it will copy m_Sample using the standard integer assignment operator. Since this is exactly what we’d be doing anyway if we wrote our own copy constructor or overloaded assignment operator, there’s really no reason to write our own version of these functions!
However, when designing classes that handle dynamically allocated memory, member wise (shallow) copying can get us in a lot of trouble! This is because the standard pointer assignment operator just copies the address of the pointer — it does not allocate any memory or copy the contents being pointed to!
A deep copy duplicates the object or variable being pointed to so that the destination (the object being assigned to) receives it’s own local copy. This way, the destination can do whatever it wants to it’s local copy and the object that was copied from will not be affected. Doing deep copies requires that we write our own copy constructors and overloaded assignment operators.

Copy Constructor :-
1) First, we have to check to make sure cSource even has a string.
2) If it does, then we allocate enough memory to hold a copy of that string.
3) Finally, we have to manually copy the string using strncpy().
Some Example Code for the Copy Constructor Dynamically allocated memory:-
Sample::Sample(const Sample& cSource)
{
// Here m_nLength is not a pointer but a simple data member of type "int", we can shallow copy it
m_nLength = cSource.m_nLength;
// m_pchString is a pointer data member in Class Sample, so we need to deep copy it if it is non-null
if (cSource.m_pchString)
{
m_pchString = new char[m_nLength];
// Copy the string into our newly allocated memory
strncpy(m_pchString, cSource.m_pchString, m_nLength);
}
else
{
m_pchString = 0;
}
}
Overloaded assignment operator:-
1) Need to deallocate any value that this string is holding!
2) Then, we have to check to make sure cSource even has a string.
3) If it does, then we allocate enough memory to hold a copy of that string.
4) Finally, we have to manually copy the string using strncpy() and return the Object reference.
Some Example Code for the Assignment operator:-
Sample& Sample::operator=(const Sample& cSource)
{
//check for self-assignment
if (this == &cSource)
return *this;
delete[] m_pchString;
m_nLength = cSource.m_nLength;
// now we need to deep copy m_pchString
if (cSource.m_pchString)
{
m_pchString = new char[m_nLength];
// Copy the parameter the newly allocated memory
strncpy(m_pchString, cSource.m_pchString, m_nLength);
}
else
{
m_pchString = 0;
}
return *this;
}
Shallow copy lead to memory leak and some other side effects. So it is better to use Deep copy than the shallow copy in C++.
Monday, January 24, 2011
Different Types New And Delete Operation in C++...
Sample Code for the New and Delete Operations in C++:-
String *ps = new String();
causes compilers to generate code that approximately corresponds to this:
operator new(sizeof(ps)); // deallocate the memory
ps->string(); // call the object's ctor
First, it allocates enough memory to hold an object of the type requested. Second, it calls a constructor to initialize an object in the memory that was allocated. The new operator always does those two things; you can't change its behavior in any way.
The operator new function is usually declared like this:
void * operator new(size_t size);
The return type is void*, because this function allocates memory first before calling constructor and returns a pointer to raw, uninitialized memory. The size_t parameter specifies how much memory to allocate. You can overload operator new by adding additional parameters, but the first parameter must always be of type size_t.
Like malloc, operator new's only responsibility is to allocate memory. It knows nothing about constructors. All operator new understands is memory allocation. It is the job of the new operator to take the raw memory that operator new returns and transform it into an object.
Similarly, The memory deallocation is performed by the operator delete function, which is usually declared like this:
void operator delete(void *memoryToBeDeallocated);
That is,
String *ps;
…………..
delete ps;
causes compilers to generate code that approximately corresponds to this:
ps->~string(); // call the object's dtor
operator delete(ps); // deallocate the memory
Here destructor is called first and then memory is deallocated. So “Operator delete” also returns void * instead of X * where X is the class of which object is created. Like “New” and “Delete” Operator pair for allocating and deallocating of memory, “Operator new” and “Operator Delete” is used. Otherwise result will create the memory leak situation.
string *ps = new string[10]; // allocate an array of objects
The new being used is still the new operator, but because an array is being created, the new operator behaves slightly differently from the case of single-object creation. For one thing, memory is no longer allocated by operator new. Instead, it's allocated by the array-allocation equivalent, a function called operator new[] (often referred to as "array new.") Like operator new, operator new[] can be overloaded. This allows you to seize control of memory allocation for arrays in the same way you can control memory allocation for single objects. Similarly the paired operator to delete the memory allocation which is assigned during the “operator new[]” is “operator delete[]”. Here the call sequence of the constructor, destructor and memory allocation and deallocation is same as the operator new and delete.
Placement Syntax:-
The Solution for overloading the operator new with the extra argument to place the object in a particular address:-
Void * Operator new (size_t , void * p)
{
Return p; //place object at ‘p’
}
And can be invoked like this:-
Void * pf = (void *)0xFOOF;
X *px = new (pf)X; //Construct X at ‘buf’ invokes operator new(size,pf) that is the placement
So Below is the summary of the three different types of new and delete operations :-
1) Using “void * Operator new(size_t);” For Dynamic Memory Allocation of normal Object
“void * Operator delete(void * memLoc);” For Dynamic Memory deallocation of nomal Object
2) Using “void * Operator new[](size_t);” For Dynamic Memory Allocation of Array of Object
“void * Operator delete[](void * memLoc);” For Dynamic Memory deallocation of array Object
Function Pointer and It's Implementation in C/C++
Function Pointer is a pointer variable, which points to the address of a function. You must keep in mind, that a running program gets a certain space in the main-memory. Both, the executable compiled program code and the used variables, are put inside this memory.
Function Pointer provides some extremely interesting, efficient and elegant programming techniques. You can use them to replace switch/if-statements, to realize your own late-binding or to implement callbacks.
Important Note:- A function pointer always points to a function with a specific signature! Thus all functions, you want to use with the same function pointer, must have the same parameters and return-type!
Example:- How to Replace a Switch-Statement by simple function pointer
// one of these functions is selected at runtime with a swicth or a function pointer
float fPlus (float a, float b) { return a+b; }
float fMinus (float a, float b) { return a-b; }
float fMultiply (float a, float b) { return a*b; }
float fDivide (float a, float b) { return a/b; }
// solution with a function pointer - pt2Func argument is a function pointer and points to a function which takes two floats and returns a float.
void Switch_With_Function_Pointer(float a, float b, float (*pt2Func)(float, float))
{
float result = pt2Func(a, b); // call using function pointer
cout << "switch replaced by function pointer: 2-5="; // display result cout << result << endl; } // execute example code void Replace_A_Switch() { cout << endl << "Executing function 'Replace_A_Switch'" << endl; Switch_With_Function_Pointer(2, 5, /* pointer to function 'Minus' */ &Minus); } Define a Function Pointer in C and C++ :-
In the C++ example it is assumed, that the function, our pointer points to, is a member function of TMyClass.
int (*pt2Function) (float, char, char); // C Declaration
int (TMyClass::*pt2Member)(float, char, char); // C+ Declaration
Assign an address to a Function Pointer :-
It's optional to use the address operator & in front of the function's name. Note: You may have got to use the complete name of the member function including class-name and scope-operator (::). Also got to ensure, that it is allowed to access the function right in scope where your assignment stands.
// C Style
int DoIt (float a, char b, char c){ cout << "DoIt" << endl; return a+b+c; } int DoMore(float a, char b, char c){ cout << "DoMore" << endl; return a-b+c; } pt2Function = DoMore; // assignment pt2Function = &DoIt; // alternative using address operator // C++ Style class TMyClass { public: int DoIt (float a, char b, char c){ cout << "TMyClass::DoIt" << endl; return a+b+c; }; int DoMore(float a, char b, char c){ cout << "TMyClass::DoMore" << endl; return a-b+c; }; /* more of TMyClass */ }; pt2Member = TMyClass::DoIt; // assignment pt2Member = &TMyClass::DoMore; // alternative using address operator Comparing Function Pointers :-
// C Style
if(pt2Function == &DoIt)
cout << "pointer points to DoIt" << endl; // C++ Style if(pt2Member == &TMyClass::DoMore) cout << "pointer points to TMyClass::DoMore" << endl; Calling a Function using a Function Pointer :-
In C :
1) Use the name of the function pointer instead of the name of the function.
2) Use explicitly dereference.
In C++:-
1) Need to have an instance of a class to call one of their (non-static) member functions. If the call takes place within another member function you can use the this-pointer.
int result1 = pt2Function (12, 'a', 'b'); // C short way
int result2 = (*pt2Function) (12, 'a', 'b'); // C
TMyClass instance;
int result3 = (instance.*pt2Member)(12, 'a', 'b'); // C++
int result4 = (*this.*pt2Member)(12, 'a', 'b'); // C++ if this-pointer can be used
Pass a Function Pointer as an Argument :-
// pt2Func is a pointer to a function which returns an int and takes a float and two char
void PassPtr(int (*pt2Func)(float, char, char))
{
float result = pt2Func(12, 'a', 'b'); // call using function pointer
cout << result << endl; } // execute example code void Pass_A_Function_Pointer() { cout << endl << "Executing 'Pass_A_Function_Pointer'" << endl; PassPtr(&DoIt); } Return a Function Pointer :-
It's a little bit tricky but a function pointer can be a function's return value. In the following example there are two solutions of how to return a pointer to a function which is taking a float and returns two float. If you want to return a pointer to a member function you have just got to change the definitions/declarations of all function pointers.
// Simple direct solution in C
// function takes a char and returns a pointer to a function which is taking two
// floats and returns a float.
float (*GetPtr1(const char opCode))(float, float)
{
if(opCode == '+') return &Plus;
if(opCode == '-') return &Minus;
}
// solution using a typedef
// define a pointer to a function which is taking two floats and returns a float
typedef float(*pt2Func)(float, float);
// function takes a char and returns a function pointer which is defined as a
// type above.
pt2Func GetPtr2(const char opCode)
{
if(opCode == '+') return &Plus;
if(opCode == '-') return &Minus;
}
// execute example code
void Return_A_Function_Pointer()
{
cout << endl << "Executing 'Return_A_Function_Pointer'" << endl; float (*pt2Function)(float, float); // define a function pointer pt2Function=GetPtr1('+'); // get function pointer from function 'GetPtr1' cout << pt2Function(2, 4) << endl; // call function using the pointer pt2Function=GetPtr2('-'); // get function pointer from function 'GetPtr2' cout << pt2Function(2, 4) << endl; // call function using the pointer } Use Arrays of Function Pointers :-
Operating with arrays of function pointers is very interesting. This offers the possibility to select a function using an index. The syntax appears difficult, which frequently leads to confusion.
// C
// type-definition: 'pt2Function' now can be used as type
typedef int (*pt2Function)(float, char, char);
// illustrate how to work with an array of function pointers
void Array_Of_Function_Pointers()
{
cout << endl << "Executing 'Array_Of_Function_Pointers'" << endl; //
// and take a float and two char
pt2Function funcArr[10];
funcArr[0] = &DoIt;
funcArr[1] = &DoMore;
/* more assignments */
// calling a function using an index to address the function pointer
cout << funcArr[1](12, 'a', 'b') << endl; cout << funcArr[0](12, 'a', 'b') << endl; } // C++ // type-definition: 'pt2Member' now can be used as type typedef int (TMyClass::*pt2Member)(float, char, char); // illustrate how to work with an array of member function pointers void Array_Of_Member_Function_Pointers() { cout << endl << "Executing 'Array_Of_Member_Function_Pointers'" << endl; //
// int and take a float and two char
pt2Member funcArr[10];
funcArr[0] = &TMyClass::DoIt;
funcArr[1] = &TMyClass::DoMore;
/* more assignments */
// calling a function using an index to address the member function pointer
// note: an instance of TMyClass is needed to call the member functions
TMyClass instance;
cout << (instance.*funcArr[1])(12, 'a', 'b') << endl; cout << (instance.*funcArr[0])(12, 'a', 'b') << endl; } In C++, one way to get late binding, which also called Dynamic binding is to use function pointers because it is not possible to know which function will be called until runtime (when the program is run). Calling a function via a function pointer is also known as an indirect function call. If you call a virtual function, your program has got to determine which one has got to be called. It does this using a V-Table containing all the possible functions. This costs some time each call and maybe you can save some time using function pointers instead of virtual functions.
How Malloc and Free are Related in C?
Every process has a region of memory, from address x to address y, called the heap. All your malloc had data lives in this area. malloc() keeps some data structure, let's say a list, of all the free chunks of space in the heap. When you call malloc, it looks through the list for a chunk that's big enough for you, returns a pointer to it, and records the fact that it's not free any more as well as how big it is. When you call free() with the same pointer, free() looks up how big that chunk is and adds it back into the list of free chunks(). If you call malloc()and it can't find any large enough chunk in the heap, it uses the brk() syscall to grow the heap, i.e. increase address y and cause all the addresses between the old y and the new y to be valid memory. brk() must be a syscall; there is no way to do the same thing entirely from userspace.
What is Setjmp and longjmp In C/C++?
These two functions are not only supported in Unix, but also used extensively in both DOS and Windows. They are a pair of instructions that can be used as a simple mechanism to quit a process. An example would be this: Consider that you have a main control function that calls other functions, and these other functions call other functions to a relatively large depth. You test for various "critical errors" in your deepest code - these are errors that cause you to stop processing the current task. Without using setjmp/longjmp, if you encountered an error in the lowest level of functions, you would have to set some flag, and return it to the calling function. This returning function would have to check this flag, and return it to its calling function, and continue up the call tree to the main control function, who would also have to check the return flag and act on the information. With setjmp/longjmp, you simply call setjmp in the main control function, and when you detect the error in the low-level function, you just call longjmp. This effectively returns directly to the main control function without having to test for error conditions within the intermediate functions. The stack will be corrected to point where your program will be able to continue execution. It is effectively a "goto" command directly from your longjmp command directly back to you setjmp command. There is a downside to this - it your intermediate functions use any temporary resources, such as allocating memory or opening files, setjmp/longjmp will not release these resources, so you have to be very careful with your design when using these. C++ has addressed this problem with its exception handling capabilities, which is far superior to using setjmp/longjmp.
In Short, a typical use of setjmp/longjmp is implementation of an exception mechanism that utilizes the ability of longjmp to reestablish program state, even across multiple levels of function calls.
Simple Example is mentioned as below:-
static jmp_buf buf;
void second(void) {
printf("second\n"); // prints
longjmp(buf,1); // jumps back to where setjmp was called - making setjmp now return 1
}
void first(void) {
second();
printf("first\n"); // does not print
}
int main() {
if ( ! setjmp(buf) ) {
first(); // when executed, setjmp returns 0
} else { // when longjmp jumps back, setjmp returns 1
printf("main\n"); // prints
}
return 0;
}
Output of the above program as mentioned is:-
second
main
Wednesday, January 19, 2011
Including C Files In C++ Files ..
Including C files in C++ Code
1st method:-
If you are including a C header file that isn't provided by the system, you may need to wrap the #include line in an extern "C" { /*...*/ } construct. This tells the C++ compiler that the functions declared in the header file are C functions.
// This is C++ code
extern "C" {
// Get declaration for f(int i, char c, float x)
#include "my-C-code.h"
}
int main()
{
f(7, 'x', 3.14); // Note: nothing unusual in the call
...
}
2nd Method:-
If you are including a C header file that isn't provided by the system, and if you are able to change the C header, you should strongly consider adding the extern "C" {...} logic inside the header to make it easier for C++ users to #include it into their C++ code. Since a C compiler won't understand the extern "C" construct, you must wrap the extern "C" { and } lines in an #ifdef so they won't be seen by normal C compilers.
Step #1: Put the following lines at the very top of your C header file (note: the symbol __cplusplus is #defined if/only-if the compiler is a C++ compiler):
#ifdef __cplusplus
extern "C" {
#endif
Step #2: Put the following lines at the very bottom of your C header file:
#ifdef __cplusplus
}
#endif
Now you can #include your C header without any extern "C" nonsense in your C++ code:
// This is C++ code
// Get declaration for f(int i, char c, float x)
#include "my-C-code.h" // Note: nothing unusual in #include line
int main()
{
f(7, 'x', 3.14); // Note: nothing unusual in the call
...
}
Functions to be called in C++ code:-
If you have an individual C function that you want to call, and for some reason you don't have or don't want to #include a C header file in which that function is declared, you can declare the individual C function in your C++ code using the extern "C" syntax. Naturally you need to use the full function prototype:
extern "C" void f(int i, char c, float x);
A block of several C functions can be grouped via braces:
extern "C" {
void f(int i, char c, float x);
int g(char* s, char const* s2);
double sqrtOfSumOfSquares(double a, double b);
}
After this you simply call the function just as if it were a C++ function:
int main()
{
f(7, 'x', 3.14); // Note: nothing unusual in the call
...
}
Some Precautions:-
If a function has more than one linkage specification, they must agree; it is an error to declare functions as having both C and C++ linkage. Furthermore, if two declarations for a function occur in a program — one with a linkage specification and one without — the declaration with the linkage specification must be first. Any redundant declarations of functions that already have linkage specification are given the linkage specified in the first declaration. For example:
extern "C" int CFunc1();
...
int CFunc1(); // Redeclaration is benign; C linkage is
// retained.
int CFunc2();
...
extern "C" int CFunc2(); // Error: not the first declaration of
// CFunc2; cannot contain linkage
// specifier.
Subscribe to:
Comments (Atom)