天天看點

其他源檔案無法調用隐函數,warning: implicit declaration of function萬惡之源:C語言中的隐式函數聲明

摘要:所謂的隐函數就是隻在本.c,或者.cpp檔案中聲明( 沒在頭檔案中聲明的函數)的函數. 對于其非本檔案的稱之為隐世函數.  

萬惡之源:C語言中的隐式函數聲明

今天在調用postgresql源碼中get_rel_name()函數時,不小心調用了隐函數get_relation_name();出現

delrelation_record.c:70:16: warning: implicit declaration of function ‘get_relation_name’ [-Wimplicit-function-declaration]
   table_name = get_relation_name(relOid);
                ^~~~~~~~~~~~~~~~~
delrelation_record.c:70:14: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
   table_name = get_relation_name(relOid);
              ^
delrelation_record.c:92:5: warning: ‘res’ may be used uninitialized in this function [-Wmaybe-uninitialized]
     PQclear(res);
           

這裡 我們比較比較get_rel_name()   和 get_relation_name()  有什麼不同.

首先:看源碼get_rel_name();

src/backend/utils/cache/lsyscache.c

char *
get_rel_name(Oid relid)
{
	HeapTuple	tp;

	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
	if (HeapTupleIsValid(tp))
	{
		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
		char	   *result;

		result = pstrdup(NameStr(reltup->relname));
		ReleaseSysCache(tp);
		return result;
	}
	else
		return NULL;
}
           

然後看get_relation_name();

src/backend/utils/adt/ruleutils.c 

/*
 * get_relation_name
 *		Get the unqualified name of a relation specified by OID
 *   和get_rel_name()  函數的不同就是多了一個判斷error的條件.
 * This differs from the underlying get_rel_name() function in that it will
 * throw error instead of silently returning NULL if the OID is bad.
 */
static char *
get_relation_name(Oid relid)
{
	char	   *relname = get_rel_name(relid);

	if (!relname)
		elog(ERROR, "cache lookup failed for relation %u", relid);
	return relname;
}
           

按理說調用哪個都可以啊.然後再看看函數聲明的位置.

get_relation_name()  在src/backend/utils/adt/ruleutils.c   和函數聲明在有一個文檔裡.

static char *get_relation_name(Oid relid);
           

而get_rel_name()  在src/include/commands/extension.h   在頭檔案裡,

外界函數想要調用它,隻需添加頭問價就可以.

extern Oid	get_extension_oid(const char *extname, bool missing_ok);
           

是以,舉個例子就會很容明白隐函數的用途.防止被外界調用.