Question

const class & versus const class in function parameter

Asked by: SteH

I found a strange error I don't really understand. I have a derived class with a virtual function. The second parameter to the call was a const reference to a class I defined in a separate dll. When compiling and debugging it I found out that inside the function not the address of the variable was known to the function but the address of the vftable of that class was used instead. Not only the values where different but even the stack got corrupted (__chkesp failed). Just buy chance I removed the reference and now everything works as expected. When am I allowed to pass a variable which doesn't change as const and by reference? At least in a copy contructor I am.

This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.

Subscribe now for full access to Experts Exchange and get

Instant Access to this Solution

  • Plus...
  • 30 Day FREE access, no risk, no obligation
  • Collaborate with the world's top tech experts
  • Unlimited access to our exclusive solution database
  • Never be left without tech help again

Subscribe Now

Asked On
2003-10-22 at 00:26:14ID20774222
Tags

vftable

,

value

Topic

C++ Programming Language

Participating Experts
4
Points
500
Comments
29

Trusted by hundreds of thousands everyday for fast, accurate and reliable tech support.

  • "The time we save is the biggest benefit of Experts Exchange to Warner Bros. What could take multiple guys 2 hours or more each to find is accessed in around 15 minutes on Experts Exchange." Mike Kapnisakis, Warner Bros.
  • "Our team likes having a resource that is more secure than just using Google and most experts using this service really know their stuff. It's nice to look here first versus using Google." Dayna Sellner, Lockheed Martin
  • "Anytime that I've been stumped with a problem, 9 out of 10 times Experts Exchange has either the accepted solution or an open discussion of the potential solution to the problem." Kenny Red, eBay Inc.

See what Experts Exchange can do for you.

Got a question?

We've got the answer.

Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.

Screenshot of Experts Exchange Knowledgebase

Need individual assistance?

Our experts are ready to help.

If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.

Screenshot of Experts Exchange Knowledgebase

Want to learn from the best?

Read articles from industry experts.

Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.

Screenshot of an Article

Working on a long term project?

Store your work and research.

Save solutions to your questions, answers you’ve discovered through searching plus helpful articles in your personal knowledgebase for easy future access.

Screenshot of Experts Exchange Knowledgebase

Access the answers to your technology questions today.

Subscribe Now

30-day free trial. Register in 60 seconds.

What Makes Experts Exchange Unique?

Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Trusted by the world's most respected brands.

image of each brand's logo

Faithfully serving IT professionals since 1996.

Experts Exchange Logo

Try it out and discover for yourself.

Subscribe Now

30-day free trial. Register in 60 seconds.

Related Solutions

  1. const
    I have trouble to initialize a const in class,where should I initialize it ? A sample is ideal. It's very urgent,please hurry up. Thanks.
  2. const array
    Hi, a simple little thing. I would like to define a constant string array, something like: public const unit(2)= "kg" "L" "Ton" But is this possible in any way??

Free Tech Articles

  1. WARNING: 5 Reasons why you should NEVER fix a computer for free.
    It is in our nature to love the puzzle. We are obsessed. The lot of us. We love puzzles. We love the challenge. We thrive on finding the answer. We hate disarray. It bothers us deep in our soul. W...
  2. SCCM OSD Basic troubleshooting
    SCCM 2007 OSD is a fantastic way to deploy operating systems, however, like most things SCCM issues can sometimes be difficult to resolve due to the sheer volume of logs to sift through and the dispe...
  3. Migrate Small Business Server 2003 to Exchange 2010 and Windows 2008 R2
    This guide is intended to provide step by step instructions on how to migrate from Small Business Server 2003 to Windows 2008 R2 with Exchange 2010. For this migration to work you will need the fo...
  4. Create a Win7 Gadget
    This article shows you how to create a simple "Gadget" -- a sort of mini-application supported by Windows 7 and Vista. Gadgets can be dropped anywhere on the desktop to provide instant information, ...
  5. Outlook continually prompting for username and password
    There have been a lot of questions recently regarding Outlook prompting for a username and password whilst using Exchange 2007. There are a few reasons why this would happen and I will try to cover t...
  6. Backup Exchange 2010 Information Store using Windows Backup
    There seems to be quite a lot of confusion around the ability to backup Exchange 2010 using the built in Windows Backup feature. This stems from the omission of this feature prior to Exchange 2007 s...

Cloud Class Webinars

  1. Avoiding Bugs in Microsoft Access
    Alison Balter takes and in-depth look at avoiding bugs in Access. In this webinar you will learn about using the immediate window to debug your applications, invoking the debugger, using breakpoints to troubleshoot, stepping through code, setting the next statement to execute, ...
  2. Top 10 Best New Features in Visio 2010
    Scott Helmers gives live demonstrations of the top 10 new features in Visio 2010. This webinar will teach you how to create compelling diagrams by adding shapes to the page with a single click, linking the shapes in a diagram to data in Excel (or SQL Server, or SharePoint), ...
  3. IT Consultant Business Secrets Revealed
    Michael Munger, Experts Exchange tech pro and IT consultant, pulls back the curtain on his very successful businesses and answers question on every IT consultant and business owner should know about. He shares secrets on what he did to solve the 5 most common problems in IT, ...
  4. Disaster Recovery and Business Continuity
    Quest CTO, Mike Billon, gives an overview of the steps involved in building a dunamic disaster recovery plan. Through case studies and an examination of software/hardware tooles for monitoring and testing, you'll gain a better understandin of where you are, where you want ...
  5. Organize Your Visio Diagrams with Containers and Lists
    Scott Helmers uses cross functional flowcharts, wireframe diagrams, data graphic legends and seating charts to teach you: how to ustilize all three new structured diagram components in Visio 2010, the best practices for organizeing shapes in previous version of Visio, how to organize ...
  6. How to Us Objects, Properties, Events and Methods in Microsoft Access
    Alison Dalter gives an in-depbth look at objects, properties, events and methods in Microsoft Access. In this webinar you will learn about using the object browser, referring to objects, working with properties and methods, working with object variables, understanding the ...

Join the Community

Give a Little. Get a Lot.

Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.

Join the Community

Answers

 

by: AlexFMPosted on 2003-10-22 at 00:35:37ID: 9596985

Can you show some code?

 

by: Sys_ProgPosted on 2003-10-22 at 00:51:06ID: 9597046

Hey I think u can pass a const reference to a derived virtual function.

I tried with it and it works fine

Post some example of your code, so that we can investigate

 

by: SteHPosted on 2003-10-22 at 00:58:52ID: 9597084

The class definition for the object to be passed is

class COORDDLL_API WorldCoord  
{
public:

[snip]

      WorldCoord();
      WorldCoord (const WorldCoord& wcPos);
      WorldCoord (double du, double dv, double dw);
      //WorldCoord (const WORLD_COORD mcPos);
      virtual ~WorldCoord();

      WorldCoord& operator= (const WorldCoord &wcPos);

      double m_dU;
      double m_dV;
      double m_dW;
};

The virtual class definition with the function is

class WorldCoord;
class FitObj
{
public:
      FitObj () {};
      virtual ~FitObj () {};
      virtual void ToWorldFit (WorldCoord& wcPos, const WorldCoord wcAct, const double dPhi = 0) = 0;
      virtual void SetPhi (double dPhi) = 0;
      virtual void SetCamPos (const WorldCoord wcPos) = 0;      // for sensor camera 1 pos and for chip rotation center
      virtual void SetOffset (const WorldCoord wcPos) = 0;      // for sensor offset from global center and for chip offset from rotation center
      virtual void SetChi2 (const double dChi2) {m_dChi2 = dChi2; return;};
      virtual double GetChi2 (void) {return m_dChi2;};
protected:
      double m_dChi2;
};

And the actual class calling the function:

typedef list<MotorCoord> MList;
typedef list<WorldCoord> WList;
#include "FitObj.h"
class CSensor : public FitObj// : public CObject
{
public:
      virtual void ToWorldFit(WorldCoord& wcPos, const WorldCoord wcAct, const double dPhi = 0); // virtual from class FitObj  
 [snip]
      void ToSensor(WorldCoord& wcPos, const WorldCoord wcAct, const double dPhi = 0);
      void ToSensor(WorldCoord& wcPos, const double dPhi = 0);
      void ToWorld(WorldCoord& wcPos, const WorldCoord wcAct, const double dPhi = 0);
      void ToWorld(WorldCoord& wcPos, const double dPhi = 0);
      void FitCoord (int n);
      CSensor();
      virtual ~CSensor(); // virtual from class FitObj  

protected:
      MotorCoord m_mcFirst;

      list<LONG>      m_clChipRot;      //< list of rotation angles of chips
      WList      m_clChipPos;      //< list of points to place chips
      WList      m_clRef;            //< list of reference points on sensor
      MList      m_clCoord;            //< list of measured motor coords of ref points
      POINT      m_pPtsFrame[5];                                          //< list of border frame points.

      MotorCoord m_mcToHead;
      MotorCoord m_mcMeasPos;
      WorldCoord m_wcOffset;
      double m_dPhi;
};

The function call with the problem was
      virtual void ToWorldFit(WorldCoord& wcPos, const WorldCoord& wcAct, const double dPhi = 0); // virtual from class FitObj  

When called via
      fpFitObj->ToWorldFit (wcPos, wcAct, phik);      // wcAct = cam1pos      // for CChip +phik is correct solution!
where fpFitObj is a pointer to the class FitObj.

 

by: AlexFMPosted on 2003-10-22 at 01:20:43ID: 9597187

Looks OK except the line:

public:
    virtual void ToWorldFit(WorldCoord& wcPos, const WorldCoord wcAct, const double dPhi = 0); // virtual from class FitObj  

there is no & after const WorldCoord (I beleive this is typo).
So, when you call this function, it fails. And When you replace with:

    virtual void ToWorldFit(WorldCoord wcPos, WorldCoord wcAct, const double dPhi = 0); // virtual from class FitObj  

it works?

 

by: SteHPosted on 2003-10-22 at 01:37:51ID: 9597267

No I first tried it with
    virtual void ToWorldFit(WorldCoord& wcPos, const WorldCoord& wcAct, const double dPhi = 0);
in FitObj and CSensor and this gave problems that inside CSensor::ToWorldFit () the address of wcAct was the WorldCoord::vftable instead of the address. I tried afterwards the version:
    virtual void ToWorldFit(WorldCoord& wcPos, const WorldCoord wcAct, const double dPhi = 0);
and then everything is working correct. But I don't really understand why I can't use the first function.

 

by: AxterPosted on 2003-10-22 at 03:09:21ID: 9597624

FYI:
The decendant virtual functions should not have default values.

 

by: Sys_ProgPosted on 2003-10-22 at 03:15:57ID: 9597649

Whatever code u have, I have simulated it into a simpler version.
Just go thru this, this code works fine


===========

#include <iostream>
#include <stdlib.h>

using namespace std;

class Obj {
} ;

class A {
  public :
    virtual void f ( const Obj &p ) {
      cout << "\nIn A" ;
    }
} ;

class B : public A {
  public :
    void f ( const Obj &p ) {
      cout << "\nIn B" ;
    }  
} ;

int main(int argc, char *argv[])
{
  A *aPtr ;
  A aObj ;
  B bObj ;
  Obj o ;
 
  // Ptr points to an object of type A
  aPtr = &aObj ;
  aPtr -> f ( o ) ;

  // Ptr points to an object of type B
  aPtr = &bObj ;
  aPtr -> f ( o ) ;
  system("\nPAUSE");      
  return 0;
}

=================

 

by: AxterPosted on 2003-10-22 at 03:21:14ID: 9597660

Since WorldCoord is a virtual class, your functions should pass the value by reference or pointer.
So it should be the following:
virtual void ToWorldFit(WorldCoord& wcPos, const WorldCoord& wcAct, const double dPhi = 0);

Here's an example of what happens when you pass a virtual class by value compared to what you get when you pass by reference.

class foo
{
public:
      foo(){x=2;}
      virtual ~foo(){}
      virtual int GetValue(){return x;}
      int x;
};

class foo_decs : public foo
{
public:
      foo_decs(){y=3;}
      ~foo_decs(){}
      int GetValue(){return x+y;}
      int y;
};


void SomeFunction_bad_via_value(foo f)
{
      cout << f.GetValue() << endl << endl;
}

void SomeFunction_good_via_ref(foo &f)
{
      cout << f.GetValue() << endl << endl;
}

void SomeFunction_good_via_ptr(foo *f)
{
      cout << f->GetValue() << endl << endl;
}

int main(int argc, char* argv[])
{
      foo_decs fd;
      SomeFunction_bad_via_value(fd);
      SomeFunction_good_via_ref(fd);
      SomeFunction_good_via_ptr(&fd);
      
      system("pause");
      return 0;
}

 

by: AxterPosted on 2003-10-22 at 03:24:57ID: 9597673

In the above code, foo_decs has over writen the GetValue function, so it should return a 5

However, when foo_decs object is passed to SomeFunction_bad_via_value function, the out put result of GetValue is 2, because the base class function gets called instead of the decendant class function.

When ever you have a virtual class, you should always setup you're functions to pass the class by reference or by pointer.

 

by: Sys_ProgPosted on 2003-10-22 at 03:31:29ID: 9597693

Hi Axter,

I think your example illustrates a good point, but u have decalred a variable of type of derived class

However the real benefit of virtual functions appear when we declare a pointer of base class point to object of either the base of derived class.

Also, his code also signifies the same thing.

I tried to simulate his example by simple classes, I think it works fine

I have pasted the code above

 

by: SteHPosted on 2003-10-22 at 03:39:10ID: 9597730

@Axter,
No WorldCoord is not a virtual class. FitObject is a pure virtual class and CSensor is the class derived of. WorldCoord is a class which is inside a DLL.

@Sys_Prog
I assumed that I can pass a const ref but why does it fail here?

@all:
I tried using
    virtual void ToWorldFit(WorldCoord& wcPos, const WorldCoord& wcAct, const double dPhi = 0);
Now inside CSensor::ToWorldFit () wcAct is not properly passed. In the debugger I look at &wcAct and it shows
00384100 WorldCoord::`vftable` instead of something line 0012e15c (a memory location on the stack). And more severe I get the error message that ESP has not been saved correctly around a function call. All this disappears when I just change the function definition to
    virtual void ToWorldFit(WorldCoord& wcPos, const WorldCoord wcAct, const double dPhi = 0);
and recompile.

Where can I look for the reason?

 

by: Sys_ProgPosted on 2003-10-22 at 04:14:56ID: 9597842

Hi SteH

I cannot figure out any problem with your code

As u know, I have coded the same thing in a simpler/illustrative way

Below is an exact replica of the situation in your code


Also regarding the value while debugging, I tried with both of the approaches - value and reference, in both ways, it shows me the same thing in debug

I think some issue with the compiler

Which one are u having

I am using a GNU compiler
===

#include <iostream>
#include <stdlib.h>

using namespace std;

class Obj {
} ;

class A {
  public :
    virtual void f ( const Obj &p ) = 0 ;
} ;

class B : public A {
  public :
    void f ( const Obj &p ) {
      cout << "\nIn B" ;
    }  
} ;

int main(int argc, char *argv[])
{
  A *aPtr ;
  B bObj ;
  Obj o ;
 
  // Ptr points to an object of type B
  aPtr = &bObj ;
  aPtr -> f ( o ) ;
  system("\nPAUSE");      
  return 0;
}

=======

 

by: SteHPosted on 2003-10-22 at 04:23:45ID: 9597862

I m using MS VC++ 6.0 with SP5. I have some other places where I can pass arguments as const refs. Escpecially copy constructors need it. But even other functions don't fail that badly. Could it be project/compiler settings used for the main app and the dlls? Some code has to reside in a DLL to avoid name conflicts with MFC. Maybe compiler/linker switches could be wrong but I tried to get them all identical. Any hints here?

 

by: Sys_ProgPosted on 2003-10-22 at 04:31:41ID: 9597894

I guess there might be something related to settings with the dll

We can test one thing

Just try doing a simple code [as illustrated above] in your environment, then try it with a dll for the Obj class

That's what I can suggest

I will try to investigate the same

 

by: AxterPosted on 2003-10-22 at 05:08:28ID: 9598070

>>No WorldCoord is not a virtual class. FitObject is a pure virtual class and CSensor is the class derived of. WorldCoord is a class which is inside a DLL.

WorldCoord is a virtual class, because it has a virtual member function.
Look at the destructor.

virtual ~WorldCoord();

That's a virtual destructor.  A class with any virtual function becomes a virtual class.

 

by: SteHPosted on 2003-10-22 at 05:35:44ID: 9598227

@Axter,
I made WorldCoord now non virtual by removing the empty destructor.

Now &wcAct is inside the function the first data element, not the vftable anymore. This means to me, that the var is put by value onto the stack and is interpreted as address by the function. So I should blame the calling function putting the value (from assembly it seems to be a temporary copy of it) and not address onto the stack. But why does it fail for a const & and not for a simple ref? Do I need some more operators/functions for the class WorldCoord?

 

by: _ys_Posted on 2003-10-22 at 05:50:44ID: 9598304

>> __chkesp failed
Seems to suggest different calling conventions being used. Just a thought.

 

by: SteHPosted on 2003-10-22 at 06:07:09ID: 9598402

@ _ys_
Yes, but why? When removing the ref from the const arg everything is fine. Otherwise everything is C++ using only calls without a modifier.

 

by: AxterPosted on 2003-10-22 at 06:34:28ID: 9598599

Can you post the implementation for the function you're referring to?

 

by: SteHPosted on 2003-10-22 at 06:44:27ID: 9598682

void CSensor::ToWorldFit(WorldCoord& wcPos, const WorldCoord& wcAct, const double dPhi /* = 0. */)
{      
      //*      correct version for fitting measured points on sensor.
      wcPos = m_wcOffset - wcPos;
      wcPos.Rotate (-m_dPhi);      // sensor rotation only depends on internal angle
      wcPos.m_dU += wcAct.m_dU;
      wcPos.m_dV += wcAct.m_dV;
      //*/
      return;
}

and the calling function
Double_t TSpecialFit::Chisquare(Int_t& npar, Double_t* par)
{
      if (fNpoints <= 0)
            return 0.;

      Double_t chisq = 0;
      Int_t n1 = fNpoints / fNrefs + 1;
      Int_t i,j,k;

      Double_t tx1, ty1;//, tx2, ty2;
      Double_t phik;
      WorldCoord wcPos, wcPos1, wcPos2, wcAct;      // current pos and camera pos
      MotorCoord mcPos;

      for (k=0;k<fNpoints;++k) {
            i = k % fNrefs;
            j = k / fNrefs;
            phik = fPhi[k] / 1000 * deg2rad;
            // Step 1

            wcPos.m_dU = fX2[k];
            wcPos.m_dV = fY2[k];
            wcPos.m_dW = 0;

            wcPos1.m_dU = par[0];
            wcPos1.m_dV = par[1];
            fpFitObj->SetOffset (wcPos1);
            wcPos1.m_dU = par[3];
            wcPos1.m_dV = par[4];
            fpFitObj->SetCamPos (wcPos1);

            switch (fiType) {
            case 3: // sensor
            case 5: // mask
                  // since ToWorld with wcAct needs to be used wcAct is set to Cam1Pos
                  wcAct.m_dU = par[3];
                  wcAct.m_dV = par[4];
                  wcAct.m_dW = 0;
                  break;
            default:
                  wcAct.m_dU = 0;
                  wcAct.m_dV = 0;
                  wcAct.m_dW = 0;
                  break;
            }
            fpFitObj->SetPhi (par[2]);
            fpFitObj->ToWorldFit (wcPos, wcAct, phik);      // wcAct = cam1pos      // for CChip +phik is correct solution!
            if ((fiType != 3) && (fiType != 5)) {
                  wcPos += wcPos1;      // subtract position of camera 2 relative to rotation center at 0/0
            }
            mcPos.ToMotor (wcPos); //, tCal);

            tx1 = fX1[k] - mcPos.m_lX;
            ty1 = fY1[k] - mcPos.m_lY;

            chisq += tx1*tx1+ty1*ty1;
      }
      return chisq;
}

 

by: _ys_Posted on 2003-10-22 at 06:58:58ID: 9598808

Verify the alignments.
What's sizeof (wcPos)?

You could also iterate through all possible calling conventions, until it works. once we know which works (if any) we may be able to reason with it.

 

by: AxterPosted on 2003-10-22 at 13:43:48ID: 9602059

Please post type for Double_t

 

by: AxterPosted on 2003-10-22 at 13:47:54ID: 9602100

It looks like the TSpecialFit::Chisquare function is using the wrong variable.
It's using a variable fNpoints instead of input variable npar.

npar is not used in the function at all.

par is being indexed, but there's nothing to verify that the constant index's are not going pass the boundry of the par array.

 

by: AxterPosted on 2003-10-22 at 13:49:24ID: 9602119

I think the problem is being cause by logic problems in the TSpecialFit::Chisquare function.
I believe memory is getting currupt before entering the CSensor::ToWorldFit function.

 

by: SteHPosted on 2003-10-23 at 00:44:21ID: 9604929

@Axter
The class TSpecialFit is part of a DLL handling an interface to ROOT http://root.cern.ch. I just modified an example, but your right I don't check whether the index for par is in range. On the other hand the number or parameters are set in another member function of TSpecialFit and all are defined by myself. So I know what I am doing here (and hope its correct). npar is the number of free parameters and therefor not helpful to check the index. For the chisquare I need all parameters even the fixed ones. fNpoints is another member variable with the number of points in fX1, fX2, fY1, and fY2 indexed by variable k.

What makes me think that ist really the call to ToWorldFit is that using
const WorldCoord wcAct
the program does its work.
When using
const WorldCoord& wcAct
the address of wcAct is the first member in wcAct and not its memory location and the difference between ESP and ESI in __chkesp is sizeof (WorldCoord) - sizeof (WorlCoord*) which means to me a value has been put on the stack and the function is looking for the address only.

Double_t is a 8 byte float on all compilers known to ROOT. For VC++ 6.0 its equal to a plain double.

@all
Thanks for all your suggestions. I will do the suggested tests later and report if this helps (alignment?).

 

by: SteHPosted on 2003-10-23 at 02:07:29ID: 9605208

@Sys_Prog
I tested your example code without any problems. I even replaced

    virtual void f ( const Obj &p ) = 0 ;

with

    virtual void (WorldCoord& wc1, const WorldCoord& wc2)

and everything works ok. I will try to get closer by using FitObj and CSensor for a next test.

 

by: SteHPosted on 2003-10-30 at 07:43:33ID: 9650868

It took me a while to do some testing with partly reduced code and simple examples. My finding is now:

the call

      fpFitObj->ToWorldFit (wcPos, wcAct, phik);

defined as

 virtual void ToWorldFit(WorldCoord& wcPos, const WorldCoord& wcAct, const double dPhi);

gets not properly compiled it seems. I had a look at the assembly of it in the debugger. The double dPhi is put on the stack, then a copy of wcAct is taken and put on the stack by value followed by the address of wcPos. The called function finds now
- the address of wcPos (4 bytes) OK
- wcAct as 24 bytes of 0; should be address
- and the value of dPhi (8 bytes). OK
but it interpretes the first 4 bytes as the address of wcPos; OK.
the next 4 bytes as the address of wcAct; very bad = 0!
and the next 8 bytes as the value of phik; here 0 instead of -0.17!

Can any #pragma in headers change this behaviour?
Any suggestions for compiler options to look at?
 I've compared all under C/C++ and Link and they agree.

 

by: SteHPosted on 2003-11-07 at 04:58:54ID: 9700800

Hi,

I just split the points for the help figuring out some bugs in the code.
Though, the problem still is not solved.

Thanks anyway

 

by: SteHPosted on 2005-01-28 at 05:17:26ID: 13162735

Meanwhile the bug is found: The DLL code was linking to an include file of an old version of the main application. The main application meanwhile has evolved. The DLL was using the old function declaration and for the main app I changed it. And only if either function matched the executable ran.

No chance for experts to find the bug, since this part I omitted the part where that header was included.

20120131-EE-VQP-002

3 Ways to Join

30-Day Free Trial

The Experts

98% positive feedback on 31,087 answers since March 2000. angeliii is a Microsoft Most Valuable Professional for his work with MS SQL Server & Develoment.

He has also proven his knowledge of Visual Basic Programming, PHP Scripting and Oracle Databases.

The Experts

97% positive feedback on 10,752 answers since July 2000. lrmoore has more than 18 years experience in the networking industry.

The six-time Mircosoft MVPs specialties include firewalls, virtual private networking, and network management.

Testimonials

"...and excellent source for support... Kind of like having your very own IT dept." Electriciansnet

Testimonials

"I was apprehensive at signing up at first. However... it has already made my life as an IT administrator much easier." JaCrews

Testimonials

"WOW! You guys have great, active, and knowledgeable people on here." moore50

Business Clients

Business Clients

In the Press

"If you’ve got a question... Experts Exchange can supply an answer.”

In the Press

"...an invaluable aid for both IT professionals and those who require tech support."

In the Press

"where IT professionals provide quick answers on just about any topic"

Business Account Plans

Loading Advertisement...