Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

static vs N_LIB_PRIVATE #16738

Open
timotheecour opened this issue Jan 16, 2021 · 1 comment
Open

static vs N_LIB_PRIVATE #16738

timotheecour opened this issue Jan 16, 2021 · 1 comment

Comments

@timotheecour
Copy link
Member

timotheecour commented Jan 16, 2021

cgen sometimes generates static, sometimes N_LIB_PRIVATE (aka __attribute__((visibility("hidden"))) on non-windows or nothing on windows)

This seems more accidental than intentional

Example

type Foo = object
  x: int

const a2 = Foo(x: 2)
let a3 = Foo(x: 3)

proc fn1(a = Foo(x: 1)) = discard
proc fn2(a = a2) = discard
proc fn3(a = a3) = discard

proc gn1(a = Foo(x: 1)) = discard
proc gn2(a = a2) = discard
proc gn3(a = a3) = discard

fn1()
fn2()
fn3()

gn1()
gn2()
gn3()

Current Output

cgen:

/* section: NIM_merge_DATA */
static NIM_CONST tyObject_Foo__n9baHnWmKzPtGzg9bGRAhg3A TM__75e9azNN0IP6k3vdklPNdtg_2 = {((NI) 1)}
;
N_LIB_PRIVATE NIM_CONST tyObject_Foo__n9baHnWmKzPtGzg9bGRAhg3A a2__EgAUY4wPCCk0Q6fNaQrdjA = {((NI) 2)}
;

/* section: NIM_merge_VARS */
N_LIB_PRIVATE NIM_CONST tyObject_Foo__n9baHnWmKzPtGzg9bGRAhg3A a3__g4JoJjaT1HO4y3vMGcGxhA = {((NI) 3)}
;

...
N_LIB_PRIVATE N_NIMCALL(void, NimMainModule)(void) {
{
	fn1__hhFs9aiaE3z26yf3IDOcHEw(TM__75e9azNN0IP6k3vdklPNdtg_2);
	fn2__hhFs9aiaE3z26yf3IDOcHEw_2(a2__EgAUY4wPCCk0Q6fNaQrdjA);
	fn3__hhFs9aiaE3z26yf3IDOcHEw_3(a3__g4JoJjaT1HO4y3vMGcGxhA);
	gn1__hhFs9aiaE3z26yf3IDOcHEw_4(TM__75e9azNN0IP6k3vdklPNdtg_2);
	gn2__hhFs9aiaE3z26yf3IDOcHEw_5(a2__EgAUY4wPCCk0Q6fNaQrdjA);
	gn3__hhFs9aiaE3z26yf3IDOcHEw_6(a3__g4JoJjaT1HO4y3vMGcGxhA);
}

Expected Output

either all use static or all use N_LIB_PRIVATE

Additional Information

I've wanted to avoid extra object creation. Or is it something that Nim compiler optimizes for me?

I noticed that cgen produces different visibility:

  • procs using inline object construction map to c static
  • all other cases map to N_LIB_PRIVATE

the other observations are

  • fn1 and gn1 use same default variable TM__75e9azNN0IP6k3vdklPNdtg_2 (thanks to const merging), and these use c static
  • fn2 and gn2 use also same default variable a2__EgAUY4wPCCk0Q6fNaQrdjA (thanks to const merging also) but these use N_LIB_PRIVATE
  • this also confirms my assumption that there is no extra object creation cost involved by inlining object constructor Foo(x: 1)

links

(EDIT)

@alaviss
Copy link
Collaborator

alaviss commented Jan 18, 2021

Something to note about static vs N_LIB_PRIVATE

  • Symbols with static are scoped to the object it resides in. Other objects can not link with those symbols.
  • Symbols with N_LIB_PRIVATE in an object can be linked with an another one, but if they are combined into a "final" object (eg. relocated .o, a dynamic library, an executable), the symbols are no longer exposed and can not be linked against.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants