C/C++

How to fix C error ‘unknown type name va_list’

Problem:

You have C code like

va_list ap;
int mode = va_arg(ap, int);

but when you try to compile it you see a warning message like

main.c: In function ‘main’:
main.c:4:2: error: unknown type name ‘va_list’
  va_list ap;
  ^~~~~~~

Solution:

Add

#include <stdarg.h>

at the top of the source file where the error occured. This will include the definitions for va_list and the va_arg function.

Posted by Uli Köhler in C/C++, GCC errors

How to fix C warning ‘implicit declaration of function va_arg’

Problem:

You have C code like

va_list ap;
int mode = va_arg(ap, int);

but when you try to compile it you see a warning message like

main.c:5:12: warning: implicit declaration of function ‘va_arg’ [-Wimplicit-function-declaration]
  int mode= va_arg(ap, int);

Solution:

Add

#include <stdarg.h>

at the top of the source file where the error occured. This will include the definitions for both va_list and va_arg.

Posted by Uli Köhler in C/C++, GCC errors

How to fix C error ‘mode_t undeclared’

Problem:

You have C code like

mode_t mode;

but when you try to compile it you see an error message like

main.c: In function ‘main’:
main.c:4:2: error: unknown type name ‘mode_t’
  mode_t mode;
  ^~~~~~

Solution:

Add

#include <sys/stat.h>

at the top of the source file where the error occured. In case you want further information about what mode_t represents, I recommend reading this blogpost.

Posted by Uli Köhler in C/C++, GCC errors

How to fix C error ‘EFAULT undeclared’

Problem:

You have C code like

errno = EFAULT;

but when you try to compile it you see an error message like

main.c:4:5: note: each undeclared identifier is reported only once for each function it appears in
main.c:4:13: error: ‘EFAULT’ undeclared (first use in this function)
     errno = EFAULT;

Solution:

Add

#include <errno.h>

at the top of the source file where the error occured. This will include both error codes like EFAULT and the global errno variable itself.

Posted by Uli Köhler in C/C++, GCC errors

How to fix C error ‘errno undeclared’

Problem:

You have C code like

errno = EFAULT;

but when you try to compile it you see an error message like

main.c: In function ‘main’:
main.c:4:5: error: ‘errno’ undeclared (first use in this function)
     errno = EFAULT;
     ^~~~~
main.c:4:5: note: each undeclared identifier is reported only once for each function it appears in
main.c:4:13: error: ‘EFAULT’ undeclared (first use in this function)
     errno = EFAULT;

Solution:

Add

#include <errno.h>

at the top of the source file where the error occured. This will include both the errno variable and specific error codes like EFAULT.

Posted by Uli Köhler in C/C++, GCC errors

How to fix GCC error ‘implicit declaration of function printf’

Problem:

You have C code like

printf("test");

but when you try to compile it you see a warning like

main.c: In function ‘main’:
main.c:2:5: warning: implicit declaration of function ‘printf’ [-Wimplicit-function-declaration]
     printf("test");
     ^~~~~~
main.c:2:5: warning: incompatible implicit declaration of built-in function ‘printf’
main.c:2:5: note: include ‘<stdio.h>’ or provide a declaration of ‘printf’

Solution:

Add

#include <stdio.h>

at the top of the source file where the warning occured.

Note that this warning message is just a warning and if you use printf correctly, your program will work even without #include <stdio.h>. However, incorrect usage of printf and similar functions will lead to hard-to-debug errors, so I recommend to add #include <stdio.h> in any case, even if it works without.

Posted by Uli Köhler in C/C++, GCC errors

How to fix C error ‘false undeclared’

Problem:

You have C code like

bool mybool = false;

but when you try to compile it you see an error message like

main.c: In function ‘main’:
main.c:2:5: error: unknown type name ‘bool’; did you mean ‘_Bool’?
     bool mybool = false;
     ^~~~
     _Bool
main.c:2:19: error: ‘false’ undeclared (first use in this function)
     bool mybool = false;
                   ^~~~~
main.c:2:19: note: each undeclared identifier is reported only once for each function it appears in

Solution:

Add

#include <stdbool.h>

at the top of the source file where the error occured.

The reason for this error is that bool is not a standard type in C (like int or char) but only in stdbool.h. Also, true and false are declared in stdbool.h.

Posted by Uli Köhler in C/C++, GCC errors

How to fix C error ‘true undeclared’

Problem:

You have C code like

bool mybool = true;

but when you try to compile it you see an error message like

main.c: In function ‘main’:
main.c:2:5: error: unknown type name ‘bool’; did you mean ‘_Bool’?
     bool mybool = true;
     ^~~~
     _Bool
main.c:2:19: error: ‘true’ undeclared (first use in this function)
     bool mybool = true;
                   ^~~~
main.c:2:19: note: each undeclared identifier is reported only once for each function it appears in

Solution:

Add

#include <stdbool.h>

at the top of the source file where the error occured.

The reason for this error is that bool is not a standard type in C (like int or char) but only in stdbool.h. Also, true and false are declared in stdbool.h.

Posted by Uli Köhler in C/C++, GCC errors

How to fix C error ‘unknown type name bool’

Problem:

You have C code like

bool mybool;

but when you try to compile it you see an error message like

main.c: In function ‘main’:
main.c:3:5: error: unknown type name ‘bool’; did you mean ‘_Bool’?
     bool mybool;
     ^~~~
     _Bool

Solution:

Add

#include <stdbool.h>

at the top of the source file where the error occured.

The reason for this error is that bool is not a standard type in C (like int or char) but only in stdbool.h.

Posted by Uli Köhler in C/C++, GCC errors

How to fix C error ‘NULL undeclared’

Problem:

You have C code like

char* ptr = NULL;

but when you try to compile it you see an error message like

main.c: In function ‘main’:
main.c:3:17: error: ‘NULL’ undeclared (first use in this function)
     void* ptr = NULL;
                 ^~~~
main.c:3:17: note: each undeclared identifier is reported only once for each function it appears in

Solution:

Add

#include <stddef.h>

at the top of the source file where the error occured.

The reason for this error is that NULL is not defined in C itself but only in stddef.h.

Posted by Uli Köhler in C/C++, GCC errors

How to get length of curve in OpenCASCADE

OCCUtils provides a convenience function to get the length of a curve in OpenCASCADE:

#include <occutils/Curve.hxx>

using namespace OCCUtils;

GeomAdaptor_Curve curve = /* ... */;

double length = Curve::Length(curve);

You can call it with GeomAdaptor_Curve or Geom_TrimmedCurve. While you can also call it with Handle(Geom_Curve), this is usually not what you want to do, since Geom_Curve typically describes an infinite curve (like an infinitely long line) and doesn’t know about which section of the curve is actually use (GeomAdaptor_Curve and Geom_TrimmedCurve both have the required Umin/Umax information stored).

In case you need to do it manually (without OCCUtils), use this snippet:

#include <GCPnts_AbscissaPoint.hxx>

GeomAdaptor_Curve curve = /* ... */;

GCPnts_AbscissaPoint::Length(curve);

For a Geom_TrimmedCurve, you need to convert it to a GeomAdaptor_Curve first. See How to convert Geom_TrimmedCurve to GeomAdaptor_Curve in OpenCASCADE for details on how to do that.

Posted by Uli Köhler in C/C++, OpenCASCADE

How to convert Geom_TrimmedCurve to GeomAdaptor_Curve in OpenCASCADE

OCCUtils provides a conveniece function to convert a Geom_TrimmedCurve to a GeomAdaptor_Curve:

#include <occutils/Curve.hxx>

using namespace OCCUtils;

Geom_TrimmedCurve input = /* ... */;

GeomAdaptor_Curve result = Curve::FromTrimmedCurve(input);

If you want to do it manually, use this snippet:

Geom_TrimmedCurve input = /* ... */;

GeomAdaptor_Curve result(
    input.BasisCurve(), input.FirstParameter(), input.LastParameter()
);
Posted by Uli Köhler in C/C++, OpenCASCADE

How to check if two gp_Pnt coincide in OpenCASCADE

If you have two points in OpenCASCADE:

gp_Pnt p1 = /* ... */;
gp_Pnt p2 = /* ... */;

you can’t just use == to check if they coincide in stock OpenCASCADE. However, OCCUtils provides operator== and operator!= for gp_Pnt among other types:

#include <occutils/Equality.hxx>

bool areTheyCoincident = p1 == p2;

If you can’t use OCCUtils, this is the way to check if they are coincident:

if (p1.Distance(p2) <= Precision::Confusion()) {
    // p1 coincides with p2
}

or alternatively:

if (p1.IsEqual(p2, Precision::Confusion())) {
    // p1 coincides with p2
}

The reason for this is that even though two points may represent the same point in space, depending on how you compute their coordinates exactly, their cartesian X/Y/Z coordinates might not be exactly identical. This is always the case with floating-point arithmetic, that’s the type of math computers use. Don’t confuse floating-point arithmetic with exact arithmetic which you have learnt in school or university.

The solution for this issue is to define a very small tolerance – any objects that have a distance less than that tolerance are considered equal.

In OpenCASCADE, Precision::Confusion() in the standard tolerance value for this.

My OCCUtils library provides

Posted by Uli Köhler in C/C++, OpenCASCADE

How to create TopoDS_Edge from to gp_Pnt in OpenCASCADE

OCCUtils provides a conveniece function for creating a TopoDS_Edge between two points (i.e. a straight line):

#include <occutils/Edge.hxx>

using namespace OCCUtils;

gp_Pnt p1 = /* ... */;
gp_Pnt p2 = /* ... */;

TopoDS_Edge edge = Edge::FromPoints(p1, p2);

In case you want to do it manually (i.e. without OCCUtils), use this snippet

TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(p1, p2).Edge();

but be aware that you also have to handle the case of p1 == p2 i.e.

if (p1.Distance(p2) <= Precision::Confusion()) {
    // Don't try to create an Edge in this case
}

OCCUtil’s Edge::FromPoints handles this case by returning TopoDS_Edge() i.e. a TopoDS_Edge where edge.IsNull() == true.

Posted by Uli Köhler in C/C++, OpenCASCADE

How to fix boost::program_options “error: ‘po’ has not been declared”

If you want to compile your C++ project using boost::program_options but you see error messages like

/home/uli/myProject/main.cpp:28:5: error: ‘po’ has not been declared
     po::notify (vm);

you are missing this declaration which you need to place directly after #include <boost/program_options.hpp>:

namespace po = boost::program_options;

This declares po as an alias for the boost::program_options namespace, because writing po::variables_map is much easier to read than boost::program_options::variables_map and using namespace boost::program_options might cause some name collisions with other functions.

Posted by Uli Köhler in Boost, C/C++

How to add boost::program_options to your CMake build

Simply add these lines to the end of your CMakeLists.txt and replace myTarget by the name of your build target (usually the first argument to add_executable(...) or add_library(...)):

# Include boost
find_package( Boost 1.30 COMPONENTS program_options REQUIRED )
target_include_directories( myTarget PRIVATE ${Boost_INCLUDE_DIR})
target_link_libraries( myTarget ${Boost_LIBRARIES} )

If you have multiple targets, copy & paste the last two lines for each target.

If you need a specific version of boost, replace 1.30 by the minimum version you need.

Posted by Uli Köhler in Boost, C/C++, CMake

How to create TopoDS_Wire from TopoDS_Edge(s) in OpenCASCADE

OCCUtils provides easy-to-use conveniece functions to convert multiple TopoDS_Edges to a TopoDS_Wire:

#include <occutils/Wire.hxx>

using namespace OCCUtils;

TopoDS_Wire& wire = Wire::FromEdges({edge1, edge2})

You can also pass a std::vector<TopoDS_Edge> to Wire::FromEdges().

If you want to do it manually without using OCCUtils, you can use BRepLib_MakeWire like this:

BRepLib_MakeWire wireMaker;
wireMaker.Add(edge1);
wireMaker.Add(edge2);
TopoDS_Wire wire = wireMaker.Wire();
Posted by Uli Köhler in C/C++, OpenCASCADE

How to export colored STEP files in OpenCASCADE

OCCUtils provides an easy way of exporting a STEP with colored elements:

#include <occutils/ExtendedSTEP.hxx>
#include <occutils/Primitive.hxx>

TopoDS_Shape cube = Primitive::MakeCube(5 /* mm */);

STEP::ExtendedSTEPExporter stepExporter;
stepExporter.AddShapeWithColor(cube, Quantity_NOC_RED);
stepExporter.Write("ColoredCube.step");

The resulting STEP file looks like this:

You can also add non-colored shapes:

stepExporter.AddShape(myShape);

Doing it without OCCUtils is possible but might make your life miserable since it’s rather hard to get to work correctly.

Here’s a minimal example:

// Get global application
Handle(TDocStd_Application) application = XCAFApp_Application::GetApplication();
// Create document
Handle(TDocStd_Document) document;
application->NewDocument("MDTV-XCAF", document);
// Get shape & color tools
Handle(XCAFDoc_ShapeTool) shapeTool = XCAFDoc_DocumentTool::ShapeTool(document->Main());
Handle(XCAFDoc_ColorTool) colorTool = XCAFDoc_DocumentTool::ColorTool(document->Main());
// Create shape
// IMPORTANT: DO NOT use shapeTool->AddShape(TopoDS_Shape)!
// This WILL NOT PRESERVE the color!
TDF_Label partLabel = shapeTool->NewShape();
shapeTool->SetShape(partLabel, filletedBody);

//TDF_Label redColor = colorTool->AddColor();
colorTool->SetColor(partLabel, Quantity_NOC_RED, XCAFDoc_ColorGen);

STEPCAFControl_Writer writer;
writer.SetColorMode(true);
writer.Perform(document, "ColoredShape.step");

What colors can you use?

Either define the Quantity_Color yourself using RGB values (from 0.0 to 1.0) like this:

Quantity_Color red(1.0 /* R */, 0.0 /* G */, 0.0 /* B */, Quantity_TypeOfColor::Quantity_TOC_RGB);

alternatively you can do the same in the HSL colorspace:

Quantity_Color brownishOrange(1.0 /* H */, 0.5 /* L */, 0.5 /* S */, Quantity_TypeOfColor::Quantity_TOC_HLS);

or you can use the predefined colors in the Quantity_NameOfColor enum – see Overview of all standard colors available in OpenCASCADE for a table of all available colors.

Posted by Uli Köhler in C/C++, OpenCASCADE