<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://community.arm.com/utility/feedstylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Help me: how to determine constant value at link time?</title><link>https://community.arm.com/developer/tools-software/tools/f/keil-forum/15263/help-me-how-to-determine-constant-value-at-link-time</link><description> In ASM51, the following code is every useful: 
 
 
 -------- file1.asm ---------
public MAX
MAX EQU 10

-------- file2.asm ---------
 extrn number(MAX) 
MOV	A,#MAX
 
 
The point is that the constant value of MAX in file2.asm can be determined at link</description><dc:language>en-US</dc:language><generator>Telligent Community 10</generator><item><title>RE: Help me: how to determine constant value at link time?</title><link>https://community.arm.com/thread/129740?ContentTypeID=1</link><pubDate>Mon, 20 Oct 2003 20:37:53 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:3b4ebc33-8ea0-4ae1-90c4-e531fedbbcb5</guid><dc:creator>Tomas Yang</dc:creator><description>&lt;p&gt;I think your explaination is quite good and everything is OK. Unfortunately, you did not resolve the problem that: ONE MORE REGISTER IS USED AND MAKE THE FUNCTION UN-REENTRANTABLE, because in my project, the function is quite complexed and one more abuse of register will make the function un-reentrantable. If you replace MAX with a constant value such as&lt;br /&gt;
&lt;br /&gt;
#define MAX 5&lt;br /&gt;
&lt;br /&gt;
then the extra register will not be used and make the function reentrantable.&lt;br /&gt;
&lt;br /&gt;
Please note that my problem is to pass MAX as a constant whose value is defined in an ASM configuration file. In your example of passing it as a funtion parameter, it&amp;#39;s meaningless to me.&lt;br /&gt;
&lt;br /&gt;
By they way, a function is &lt;b&gt;inherently reentrantable&lt;/b&gt; if it only uses registers as local automatic variables. The &amp;quot;reentrant&amp;quot; keywork is using a software stack to realize reentrant feature. If you are not clear about this, you will hardly understant my question. For example, such functions as &amp;quot;memcpy&amp;quot;, &amp;quot;isdigit&amp;quot; are reentrant (please refer to the manual), but they don&amp;#39;t use software stack at all.&lt;br /&gt;
&lt;br /&gt;
Now. Please see the result of my &amp;quot;optimization defect&amp;quot; example:&lt;br /&gt;
&lt;br /&gt;
Example 1:&lt;br /&gt;
&lt;pre&gt;#define MAX 5
uint8 Test(uint8 i)
{
	if(i == (uint8)MAX)
		return (uint8)MAX;
	return 0;
}&lt;/pre&gt;
The ASM code is:&lt;br /&gt;
&lt;pre&gt;
0000 BF0503            CJNE    R7,#05H,?C0140
0003 7F05              MOV     R7,#05H
0005 22                RET
0006         ?C0140:
0006 7F00              MOV     R7,#00H
0008 22                RET     &lt;/pre&gt;
It has 3 instrunctions excluding &amp;quot;RET&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Example 2:&lt;br /&gt;
Just replace the &lt;b&gt;define&lt;/b&gt; statement to:&lt;br /&gt;
&lt;pre&gt;extern uint8 MAX[1];&lt;/pre&gt;
now the ASM code is:&lt;br /&gt;
&lt;pre&gt;0000 AE07              MOV     R6,AR7
0002 7F00        E     MOV     R7,#LOW MAX
0004 EF                MOV     A,R7
0005 B50601            CJNE    A,AR6,?C0140
0008 22                RET
0009         ?C0140:
0009 7F00              MOV     R7,#00H
000B 22                RET     &lt;/pre&gt;
It has 5 instrunctions excluding &amp;quot;RET&amp;quot;&lt;br /&gt;
&lt;br /&gt;
We exclude &amp;quot;RET&amp;quot; from calculation since in our real project, the function is quiet complex and the size grows larger, while the &amp;quot;RET&amp;quot; statment remains the same number of occurrence.&lt;br /&gt;
&lt;br /&gt;
Example 1, good result, nothing to blame.&lt;br /&gt;
In example 2, Keil treat MAX as a variable and try to save it in a cache, which is R7, for further operation,  this is what the &amp;quot;register variables&amp;quot; does.&lt;br /&gt;
&lt;br /&gt;
As a result, in the real project, if we use &amp;quot;extern uint8 MAX[1]&amp;quot; method to pass configuration constant, the function will become larger, exhaust all registers and make the function non-reentrantable.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Help me: how to determine constant value at link time?</title><link>https://community.arm.com/thread/121865?ContentTypeID=1</link><pubDate>Mon, 20 Oct 2003 17:48:56 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:bd57199f-9301-42ef-9aaf-0bd499891a71</guid><dc:creator>Andy Neil</dc:creator><description>&lt;p&gt;&lt;i&gt;&amp;quot;At last I found that the problem lies in the optimization defects of Keil.&amp;quot;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
Or perhaps in your understanding of the &amp;#39;C&amp;#39; programming language?&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&amp;quot;You may find the translated ASM code quite different.&amp;quot;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
Well of course you will - the two source functions are quite different:&lt;br /&gt;
The &amp;quot;ideal&amp;quot; function only has to choose one of the two manifest constants &lt;b&gt;0&lt;/b&gt; or &lt;b&gt;1&lt;/b&gt;; the &amp;quot;real&amp;quot; function may have to return the actual &lt;i&gt;value&lt;/i&gt; of the symbol MAX&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&amp;quot;Keil consider MAX as constant in the first example&amp;quot;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
That&amp;#39;s because it &lt;i&gt;&lt;b&gt;is&lt;/b&gt;&lt;/i&gt; a constant: you defined MAX as an array; in &amp;#39;C&amp;#39;, using the array &lt;i&gt;name&lt;/i&gt; on its own like this (with no index) is effectively a &lt;b&gt;constant &lt;i&gt;pointer:&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;MAX&amp;quot; is equivalent to &amp;quot;&amp;amp;MAX[0]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&amp;quot;But in the seconds example, MAX is used twice&amp;quot;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
Of course it is - because you used it twice in the source code!&lt;br /&gt;
First, in the comparison operation;&lt;br /&gt;
Second, in the &lt;b&gt;return&lt;/b&gt; operation&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&amp;quot;so the &amp;#39;register variables&amp;#39; optimization takes effect, which will save i to R7, and then load MAX to R7, so as to use MAX in the return statement.&amp;quot;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
What else could it do?&lt;br /&gt;
Look at the C51 calling convention in the &lt;b&gt;Manual&lt;/b&gt; - that defines what registers &lt;i&gt;&lt;b&gt;must&lt;/b&gt;&lt;/i&gt; be used for passing parameters &amp;amp; return values.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&amp;quot;As a result, the second function will use one more register and the ASM code size is doubled!&amp;quot;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
I make it 11 bytes for the 1st function, and 12 for the second - methinks thou dost protest too much!&lt;pre&gt;             ; FUNCTION _idealTest (BEGIN)
                                           ; SOURCE LINE # 6
;---- Variable &amp;#39;i&amp;#39; assigned to Register &amp;#39;R7&amp;#39; ----
                                           ; SOURCE LINE # 7
                                           ; SOURCE LINE # 8
0000 7400        E     MOV     A,#LOW MAX
0002 B50703            CJNE    A,AR7,?C0001
                                           ; SOURCE LINE # 9
0005 7F01              MOV     R7,#01H
0007 22                RET
0008         ?C0001:
                                           ; SOURCE LINE # 10
0008 7F00              MOV     R7,#00H
                                           ; SOURCE LINE # 11
000A         ?C0002:
000A 22                RET
             ; FUNCTION _idealTest (END)&lt;/pre&gt;&lt;pre&gt;             ; FUNCTION _realTest (BEGIN)
                                           ; SOURCE LINE # 14
;---- Variable &amp;#39;i&amp;#39; assigned to Register &amp;#39;R6&amp;#39; ----
0000 AE07              MOV     R6,AR7
                                           ; SOURCE LINE # 15
                                           ; SOURCE LINE # 16
0002 7F00        E     MOV     R7,#LOW MAX
0004 EF                MOV     A,R7
0005 B50601            CJNE    A,AR6,?C0003
                                           ; SOURCE LINE # 17
0008 22                RET
0009         ?C0003:
                                           ; SOURCE LINE # 18
0009 7F00              MOV     R7,#00H
                                           ; SOURCE LINE # 19
000B         ?C0004:
000B 22                RET
             ; FUNCTION _realTest (END)&lt;/pre&gt;
&lt;br /&gt;
If you&amp;#39;re desperate to reduce the size of the &lt;i&gt;function,&lt;/i&gt; you might like to try this:&lt;pre&gt;uint8 goodTest( const uint8 testmax, uint8 i)
{
	if(i == (uint8)testmax)
		return (uint8)testmax;
	return 0;
}&lt;/pre&gt;Which uses only 8 bytes of assembler - because I&amp;#39;ve been careful to force MAX to be in the right register to start with:&lt;pre&gt;             ; FUNCTION _goodTest (BEGIN)
                                           ; SOURCE LINE # 21
;---- Variable &amp;#39;testmax&amp;#39; assigned to Register &amp;#39;R7&amp;#39; ----
;---- Variable &amp;#39;i&amp;#39; assigned to Register &amp;#39;R5&amp;#39; ----
                                           ; SOURCE LINE # 22
                                           ; SOURCE LINE # 23
0000 ED                MOV     A,R5
0001 B50701            CJNE    A,AR7,?C0005
                                           ; SOURCE LINE # 24
0004 22                RET
0005         ?C0005:
                                           ; SOURCE LINE # 25
0005 7F00              MOV     R7,#00H
                                           ; SOURCE LINE # 26
0007         ?C0006:
0007 22                RET
             ; FUNCTION _goodTest (END)&lt;/pre&gt;but it (probably) increases the &lt;i&gt;call&lt;/i&gt; overhead!  :-(&lt;br /&gt;
But the call overhead will always be your downfall when implementing trivial operations as &amp;#39;C&amp;#39; functions!&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&amp;quot;My project is an Operation system, which requires that most functions be concise and reentrantable.&amp;quot;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
But C51 is &lt;i&gt;&lt;b&gt;inherently&lt;/b&gt;&lt;/i&gt; non-reentrant - as clearly stated in the &lt;b&gt;Manual!&lt;/b&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Help me: how to determine constant value at link time?</title><link>https://community.arm.com/thread/121861?ContentTypeID=1</link><pubDate>Mon, 20 Oct 2003 11:51:15 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:6143426b-7549-4373-b4cb-ccdd150f74ce</guid><dc:creator>HansBernhard Broeker</dc:creator><description>&lt;p&gt;You don&amp;#39;t give any real explanation why the differences in behaviour of the code for these two particular functions would constitute an optimizer defect.&lt;br /&gt;
&lt;br /&gt;
C51 functions aren&amp;#39;t reentrant unless you &lt;b&gt;ask&lt;/b&gt; for them to be.  That has nothing to do with the subject of this thread.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Help me: how to determine constant value at link time?</title><link>https://community.arm.com/thread/110170?ContentTypeID=1</link><pubDate>Sat, 18 Oct 2003 20:28:06 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:2ec43753-52c1-4a0c-a07d-fd0391e8f4f3</guid><dc:creator>Tomas Yang</dc:creator><description>&lt;p&gt;Dear Hans-Bernhard Broeker, and all those who concern my question,&lt;br /&gt;
&lt;br /&gt;
Actually, I know all the ways everybody have mentioned. And I have tried even more.&lt;br /&gt;
&lt;br /&gt;
At last I found that the problem lies in the optimization defects of Keil. Let me expain in detail.&lt;br /&gt;
&lt;br /&gt;
Define in a configuration asm:&lt;br /&gt;
&lt;pre&gt;MAX equ 10
public MAX&lt;/pre&gt;
&lt;br /&gt;
Then declare the variable in C:&lt;br /&gt;
&lt;pre&gt;extern unsigned char MAX[1];&lt;/pre&gt;
&lt;br /&gt;
Now lets look at this ideal function:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;uint8 Test(uint8 i)
{
	if(i == (uint8)MAX)
		return &lt;b&gt;1&lt;/b&gt;;
	return 0;
}&lt;/pre&gt;
&lt;br /&gt;
and this real one:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;uint8 Test(uint8 i)
{
	if(i == (uint8)MAX)
		return &lt;b&gt;(uint8)MAX&lt;/b&gt;;
	return 0;
}&lt;/pre&gt;
&lt;br /&gt;
You may find the translated ASM code quite different. Keil consider MAX as constant in the first example,  which refers to MAX only once, so CJNE is used to make good (not perfect) ASM code. But in the seconds example, MAX is used twice, so the &lt;i&gt;&amp;quot;register variables&amp;quot;&lt;/i&gt; optimization takes effect, which will save &lt;i&gt;i&lt;/i&gt; to &lt;i&gt;R7&lt;/i&gt;, and then load MAX to &lt;i&gt;R7&lt;/i&gt;, so as to use MAX in the &lt;i&gt;return&lt;/i&gt; statement.&lt;br /&gt;
&lt;br /&gt;
As a result, the second function will use one more register and the ASM code size is doubled! My project is an Operation system, which requires that most functions be concise and reentrantable. Unfortunately, when this trick is used, my OS functions fail to be reentrantable! I don&amp;#39;t want to use full ASM as this OS can be transplanted to other CPU core.&lt;br /&gt;
&lt;br /&gt;
I really need this link-time constant determination, because I don&amp;#39;t want to share my source code. Currently, my solution is to use&lt;br /&gt;
&lt;pre&gt;extern code uint8 MAX&lt;/pre&gt;
and then define the value of MAX in an configuration ASM file. In this way, the &amp;quot;register variables&amp;quot; optimization is less effective and produce acceptable code.&lt;br /&gt;
&lt;br /&gt;
So, thanks to you all, and I wish Keil will do better in the future version. But I don&amp;#39;t know whether that&amp;#39;s hopeful.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Help me: how to determine constant value at link time?</title><link>https://community.arm.com/thread/95247?ContentTypeID=1</link><pubDate>Fri, 17 Oct 2003 03:23:38 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:a10ba942-2ce5-4be6-a097-2064689c4034</guid><dc:creator>Andy Neil</dc:creator><description>&lt;p&gt;&lt;i&gt;&amp;quot;One year has passed but nobody give me a good answer.&amp;quot;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
Well, I&amp;#39;m sorry - I didn&amp;#39;t realise I was supposed to drop everything and concentrate on &lt;i&gt;your&lt;/i&gt; problem!&lt;br /&gt;
&lt;br /&gt;
Anyway, think about what the Linker does: it deals with &lt;i&gt;addresses&lt;/i&gt; - you define a symbol in &amp;#39;C&amp;#39;, and the Linker fixes its &lt;i&gt;address&lt;/i&gt;.&lt;br /&gt;
Therefore, if you want the Linker to give a constant back to &amp;#39;C&amp;#39;, it will be as the &lt;i&gt;address&lt;/i&gt; of a &amp;#39;C&amp;#39; symbol.&lt;br /&gt;
Your &amp;#39;C&amp;#39; code will have to take the &lt;i&gt;address&lt;/i&gt; of the symbol, and interpret that &lt;i&gt;address&lt;/i&gt; value as the required constant (probably &lt;i&gt;via&lt;/i&gt; a cast).&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Help me: how to determine constant value at link time?</title><link>https://community.arm.com/thread/110168?ContentTypeID=1</link><pubDate>Fri, 17 Oct 2003 02:40:06 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:eab79cdb-ba2a-4162-a6c6-80d18379812d</guid><dc:creator>Abdul Mujid Kassim</dc:creator><description>&lt;p&gt;Hi,&lt;br /&gt;
  I have the following line in my assembly code and I want to link with C program. How to declare in C?&lt;br /&gt;
&lt;br /&gt;
EXTRN NUMBER (RS485_TASK, RECV_END)&lt;br /&gt;
&lt;br /&gt;
Thanks in advance.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Help me: how to determine constant value at link time?</title><link>https://community.arm.com/thread/95252?ContentTypeID=1</link><pubDate>Mon, 22 Sep 2003 05:11:00 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:5f784a42-7e67-484d-9b94-5d8c169cd0d6</guid><dc:creator>HansBernhard Broeker</dc:creator><description>&lt;p&gt;&lt;i&gt;One year has passed but nobody give me a good answer.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
... That same year also passed without any feedback from you about the answers you did get.  If you didn&amp;#39;t consider those &amp;quot;good&amp;quot; answers, why wait all of a whole year to say so?&lt;br /&gt;
&lt;br /&gt;
Are you actually trying to make us believe it never occured to you that the reason none of the answers were to your liking might have been that the trick you&amp;#39;re trying to pull is impossible?  Even in the ligth of some of your answers telling you exactly that?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Help me: how to determine constant value at link time?</title><link>https://community.arm.com/thread/95254?ContentTypeID=1</link><pubDate>Fri, 19 Sep 2003 20:34:55 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:326e83c8-f029-42dc-8b3a-2c5ada67ee0b</guid><dc:creator>Drew Davis</dc:creator><description>&lt;p&gt;The usual way to do this in C would be to supply a header file with some definitions:&lt;br /&gt;
&lt;br /&gt;
config.h&lt;br /&gt;
extern U8 const myVal;&lt;br /&gt;
&lt;br /&gt;
and tell users of the library that they need to create an object file that defines values for those constants.&lt;br /&gt;
&lt;br /&gt;
config.c:&lt;br /&gt;
U8 const myVal = 99;&lt;br /&gt;
&lt;br /&gt;
You then link config.o with the rest of your library.&lt;br /&gt;
&lt;br /&gt;
Typically, use of myVal will generate code that loads myVal from some address (determined by the linker) -- something like (at a guess)&lt;br /&gt;
&lt;br /&gt;
; small model&lt;br /&gt;
MOV R0,#myVal&lt;br /&gt;
MOV A,@R0&lt;br /&gt;
&lt;br /&gt;
; large model&lt;br /&gt;
MOV DPTR,#myVal&lt;br /&gt;
MOVX A,@DPTR&lt;br /&gt;
&lt;br /&gt;
This code will be larger than code that loads a value as an immediate value.  That is, the value is included literally in the instruction, not by reference.&lt;br /&gt;
&lt;br /&gt;
MOV A,#99&lt;br /&gt;
&lt;br /&gt;
If this difference is important to you, then life will be a little more painful.   When the assembler runs, it actually generates code like this:&lt;br /&gt;
&lt;br /&gt;
0100: MOV A,#00&lt;br /&gt;
&lt;br /&gt;
along with an entry in the object file that says &amp;quot;label MAX is at address 101&amp;quot;.  The linker then replaces the byte at address 101 with the value defined for MAX.&lt;br /&gt;
&lt;br /&gt;
There is no way to write C code with a &amp;quot;placeholder&amp;quot; value such as the EXTERN NUMBER in the assembler.  (Such syntax would have to look something like:&lt;br /&gt;
&lt;br /&gt;
U16 myMax = ???;&lt;br /&gt;
&lt;br /&gt;
where &amp;quot;???&amp;quot; is the value to be replaced by the linker.  So, there&amp;#39;s no way to write C to get that &amp;quot;to be determined&amp;quot; integer.&lt;br /&gt;
&lt;br /&gt;
There is a way to cheat, though.  It&amp;#39;s easy to write C code that generates &lt;i&gt;addresses&lt;/i&gt; that get patched up by the linker.  And you can cast an address.  So, you could write C thus:&lt;br /&gt;
&lt;br /&gt;
extern U8 MAX;  // type doesn&amp;#39;t really matter&lt;br /&gt;
U16 myMax = (U16)&amp;MAX;&lt;br /&gt;
&lt;br /&gt;
Now, all you have to do is tell your linker the address of MAX.  It will find all references to the address-of-MAX in the object files and fix them up, thus replacing the value in line, as desired.&lt;br /&gt;
&lt;br /&gt;
I find this technique &amp;quot;painful&amp;quot; because on the one hand, it&amp;#39;s not really obvious what you&amp;#39;re doing.  It obscures the real type and purpose of MAX.  And every linker has its own idiosyncratic way of defining symbols, so it&amp;#39;s a really non-portable technique.  Unless the few extra bytes of code are really going to cripple your application, you might want to just use the first method.&lt;br /&gt;
&lt;br /&gt;
Yet another method would be to distribute source code (obfuscated, perhaps, if piracy is a concern), put the definitions in a common header file, and have the user recompile the whole works.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Help me: how to determine constant value at link time?</title><link>https://community.arm.com/thread/54853?ContentTypeID=1</link><pubDate>Fri, 19 Sep 2003 19:30:22 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:1df2e6a5-3a37-429b-921b-6a0a3fadddde</guid><dc:creator>Tomas Yang</dc:creator><description>&lt;p&gt;One year has passed but nobody give me a good answer.&lt;br /&gt;
&lt;br /&gt;
I insist on &amp;quot;linking&amp;quot; the constant, because I am generating a LIB file, whose internal configuration constants should be defined by user.&lt;br /&gt;
&lt;br /&gt;
So, can any one give me better answer?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Help me: how to determine constant value at link time?</title><link>https://community.arm.com/thread/39468?ContentTypeID=1</link><pubDate>Thu, 05 Dec 2002 11:48:21 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:e0604468-3228-42c6-b0cd-807670d4305c</guid><dc:creator>HansBernhard Broeker</dc:creator><description>&lt;p&gt;I think you&amp;#39;re looking at the wrong type of &amp;quot;constant&amp;quot; on the C side of that problem.  C preprocessor macros are absolutely and strictly local to each source file. They&amp;#39;re gone completely before the code even reaches the main compiler, let alone anything gets written into any object file. In this respect, C macros are completely different than what you&amp;#39;re used to find in macro assemblers.&lt;br /&gt;
&lt;br /&gt;
C doesn&amp;#39;t really have the concept of a symbolic constant, certainly none that could be linked in from another, separately compiled source file.&lt;br /&gt;
&lt;br /&gt;
OTOH: why insist on having all this work done by the linker? A simple shared #include file containing a line like&lt;br /&gt;
&lt;br /&gt;
 &lt;pre&gt;#define MAX 10&lt;/pre&gt;
&lt;br /&gt;
should suffice.&lt;br /&gt;
&lt;br /&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Help me: how to determine constant value at link time?</title><link>https://community.arm.com/thread/39469?ContentTypeID=1</link><pubDate>Thu, 05 Dec 2002 11:48:07 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:4d52555e-6278-48ac-a416-4553fedc02d6</guid><dc:creator>Walt Conley</dc:creator><description>&lt;p&gt;Place the #define in a header file and include the header file in c files that use MAX.&lt;br /&gt;
&lt;br /&gt;
for instance in file.h&lt;br /&gt;
#define MAX 10&lt;br /&gt;
&lt;br /&gt;
In file1.c and/or file2.c&lt;br /&gt;
#include &amp;quot;file.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
if ( count &amp;lt; MAX )&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>