I have spent 2 days chasing an issue involving C++ container, std::list
, and C-Style structs. Is the following undefined behavior (Note the type for the std::list
parameter)?
#include <list>
#include <iostream>
using std::cout;
using std::endl;
struct Point_Struct
{
int x;
int y;
};
typedef struct Point_Struct Point;
int main()
{
std::list<Point> line;
Point p;
p.x = 3;
p.y = 10;
line.push_back(p);
cout << "Size of container: " << line.size() << "\n";
// Here's the issue:
line.pop_back();
// The size should be zero.
cout << "Size of container after pop_back(): " << line.size() << "\n";
return 0;
}
I ran this on Visual Studio 2017 and I get an exception error, 0xC0000005, (memory access) on the call to pop_back
.
The exception is also thrown on any method that changes the ordering of the items in the list
, such as assignment and sort
.
If I change the type of line
to std::list<Point_Struct>
, there are no exceptions thrown.
Note: The issue was found in a larger program. The code above illustrates the root cause of the issue: std::list<typedef struct>
vs. std::list<struct>
Note: The exception is thrown in VS2017 debug mode but not in release mode.
Sorry, but multiple questions follow:
Is there anything in standard C++ (11 or later) declaring undefined
behavior for using a typedef
instead of a struct
as the template
parameter for std::list
?
Would this be a Visual Studio bug?
I haven't tried on G++ or other compilers.
Edit 1: VS2017 version info
Microsoft Visual Studio Professional 2017
Version 15.9.14
Installed product: Visual C++ 2017 - 00369-60000-00001-AA071
Compilation Info
Configuration: Debug
Platform: Win32
Warning Level: Level3 (/W3)
Optimization: Disabled (/Od)
Enable C++ Exception: Yes (/EHsc)
Basic Runtime Checks: Both (/RTC1)
Disable Language Extensions: No
Conformance mode: No
Platform
Platform: Windows 7
I compiled and ran your code with g++ 11 in Eclipse (Ubuntu 18) and it worked perfectly,
Output:
Size of container: 1
Size of container after pop_back(): 0
Have you tried/is it possible to swap typedef
for using
? This might fix it:
#include <list>
#include <iostream>
using std::cout;
using std::endl;
struct Point_Struct
{
int x;
int y;
};
using Point = Point_Struct;
int main()
{
std::list<Point> line;
Point p;
p.x = 3;
p.y = 10;
line.push_back(p);
cout << "Size of container: " << line.size() << "\n";
// Here's the issue:
line.pop_back();
// The size should be zero.
cout << "Size of container after pop_back(): " << line.size() << "\n";
return 0;
}
User contributions licensed under CC BY-SA 3.0