Bug 1217293 - wrong orders of constructor
Summary: wrong orders of constructor
Keywords:
Status: CLOSED NOTABUG
Alias: None
Product: Red Hat Enterprise Linux 7
Classification: Red Hat
Component: gcc
Version: 7.0
Hardware: x86_64
OS: Linux
unspecified
high
Target Milestone: rc
: ---
Assignee: Jakub Jelinek
QA Contact: qe-baseos-tools-bugs
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2015-04-30 02:37 UTC by 韩进
Modified: 2015-05-07 09:00 UTC (History)
4 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2015-05-07 09:00:53 UTC
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)
function run before constructor; different source order with different outputs (10.00 KB, application/x-tar)
2015-04-30 02:37 UTC, 韩进
no flags Details


Links
System ID Private Priority Status Summary Last Updated
CentOS 15043010 0 None None None Never

Description 韩进 2015-04-30 02:37:44 UTC
Created attachment 1020390 [details]
function run before constructor; different source order with different outputs

Description of problem:


Version-Release number of selected component (if applicable):


How reproducible:


Steps to Reproduce:
1.
2.
3.

Actual results:


Expected results:


Additional info:

Comment 1 韩进 2015-04-30 02:40:38 UTC
the first outputs:
manager_init
manager.h,B,13,file:manager.c,0x6020c0
manager.c,run,b->run,0x6020c0
c register:0
manager.h,B,13,file:c.c,0x6020c4
manager.c,run,b->run,0x6020c0
b register:0
manager.h,B,13,file:b.c,0x6020c8
a register:-1
manager.h,B,13,file:a.c,0x6020cc
main_init
A::A
eng [0]not exist
eng [1]:b,1
eng [2]:c,2
eng [3]not exist
eng [4]not exist
eng [5]not exist
eng [6]not exist
eng [7]not exist
A::~A
manager.h,~B,17,0x6020cc
manager.h,~B,17,0x6020c8
manager.h,~B,17,0x6020c4
manager.h,~B,17,0x6020c0
main_exit
a exit
b exit
c exit
manager_exit


the second outputs:
manager.c,run,b->run,0x6020c0
c register:0
manager.h,B,13,file:c.c,0x602064
manager.c,run,b->run,0x6020c0
b register:0
manager.h,B,13,file:b.c,0x602068
a register:-1
manager.h,B,13,file:a.c,0x60206c
main_init
A::A
manager_init
manager.h,B,13,file:manager.c,0x6020c0
eng [0]not exist
eng [1]:b,1
eng [2]:c,2
eng [3]not exist
eng [4]not exist
eng [5]not exist
eng [6]not exist
eng [7]not exist
manager.h,~B,17,0x6020c0
A::~A
manager.h,~B,17,0x60206c
manager.h,~B,17,0x602068
manager.h,~B,17,0x602064
manager_exit
main_exit
a exit
b exit
c exit

Comment 2 韩进 2015-04-30 02:54:56 UTC
Comment on attachment 1020390 [details]
function run before constructor; different source order with different outputs

two Makefile:
CFLAGS += -Wall
all:constructortest constructortest1
constructortest:c.c b.c a.c main.c manager.c
        g++ -o $@ $^
constructortest1:manager.c c.c b.c a.c main.c
        g++ -o $@ $^

Comment 4 Jakub Jelinek 2015-04-30 09:45:41 UTC
Can you expand on what exactly you think is wrong and why?
Generally, mixing C++ global ctors/dtors with functions with constructor/destructor is a bad idea, if you want a particular ordering, you'd better use constructor priorities or separate files for the C++ and attribute ctors/dtors.

Comment 5 韩进 2015-05-04 09:43:48 UTC
Thanks for your reply!(I'm sorry so late. 3 days without Internet)
I simplify the program:
a.c:
#include "manager.h"
#include <stdlib.h>
#include <stdio.h>

static B b(__FILE__);
__attribute__((constructor)) void a_init(void)
{
        struct eng * a_eng = (struct eng*)malloc(sizeof(struct eng));
        a_eng->name = "a";
        a_eng->eng_id = 1;
        int ret = eng_register(a_eng);
        if(ret  < 0)
                free(a_eng);
}
__attribute__((destructor)) void a_exit(void)
{
}


manager.c:
static struct eng *eng_manager[ENG_COUNT];

static B b(__FILE__);
void print_manager(void)
{
}
int eng_register(struct eng * _eng)
{
        int idx = _eng->eng_id;
        if(idx >= ENG_COUNT || eng_manager[idx] != NULL)
                return -1;
        eng_manager[idx] = _eng;
        b.run();
        return 0;
}

void B::run(void)
{
        printf("%s,%s,b->run,%p\n",__FILE__,__func__,this);
if I use :
             constructortest:a.c main.c manager.c
                 g++ -o $@ $^ 
compile the program,in file manager.c, b.run() run before b.B()  ,outputs:
             
manager.c,run,b->run,0x6010c0
manager.h,B,13,file:a.c,0x601064
manager.h,B,13,file:manager.c,0x6010c0
manager.h,~B,17,0x6010c0
manager.h,~B,17,0x601064


but if I use:
             constructortest:manager.c a.c main.c 
                 g++ -o $@ $^
the outputs:
manager.h,B,13,file:manager.c,0x6010c0
manager.c,run,b->run,0x6010c0
manager.h,B,13,file:a.c,0x6010c4
manager.h,~B,17,0x6010c4
manager.h,~B,17,0x6010c0



"Generally, mixing C++ global ctors/dtors with functions with constructor/destructor is a bad idea." Can I think the compiler doesn't support the mixing use of ctors/dtors and constructor/destructor ? 
  Thank you!

Comment 6 Jason Merrill 2015-05-04 14:31:48 UTC
(In reply to 韩进 from comment #5)
> "Generally, mixing C++ global ctors/dtors with functions with
> constructor/destructor is a bad idea." Can I think the compiler doesn't
> support the mixing use of ctors/dtors and constructor/destructor ? 

It supports mixing them, but the ordering is unspecified.

Comment 7 韩进 2015-05-05 05:36:39 UTC
(In reply to Jason Merrill from comment #6)
> (In reply to 韩进 from comment #5)
> > "Generally, mixing C++ global ctors/dtors with functions with
> > constructor/destructor is a bad idea." Can I think the compiler doesn't
> > support the mixing use of ctors/dtors and constructor/destructor ? 
> 
> It supports mixing them, but the ordering is unspecified.

Thank you very much!


Note You need to log in before you can comment on or make changes to this bug.