هم‌اثرسازی کیست؟ توضیح بده.
در محاسبات، هم‌اثرسازی موقعیتی را شرح می‌دهد که مکان یک داده در حافظه از طریق چند نشانه‌ی (اسم متغیر) مختلف در برنامه قابل دسترسی است. بنابراین، تغییر آن داده از طریق یک نشانه به طور ضمنی مقدار مربوط به همه‌ی نام‌های مستعار (اسم متغیر) را تغییر می‌دهد، که ممکن است برنامه‌نویس انتظار آن را نداشته باشد. در نتیجه، هم‌اثرسازی، باعث می‌شود به طور خاص درک، تحلیل و بهینه‌سازی برنامه دشوار شود. تحلیلگران هم‌اثرسازی می‌خواهند اطلاعات مفیدی برای فهمیدن هم‌اثرسازی در برنامه‌ها تولید و محاسبه کنند.مثال‌ها.سرریز میانگیر (بافر).برای مثال اکثر پیاده‌سازی‌های زبان برنامه‌نویسی C بررسی حدود (چک کردن اندازه) آرایه را انجام نمی‌دهند. در نتیجه کامپایلر و قراردادهای زبان اسمبلی مربوط به معماری کامپیوتر می‌توانند از نوع پیاده‌سازی زبان برنامه‌نویسی برای رسیدن به اثر هم‌اثرسازی از طریق نوشتن مقدار خارج حدود آرایه (نوعی از سرریز میانگیر) استفاده کنند. این موضوع، بر اساس مشخصات زبان C رفتار نامشخص را فراخوانی می‌کند؛ در حالی که بسیاری از پیاده‌سازی‌های C نوعی از هم‌اثرسازی که در این جا شرح داده شد را تشخیص نمایش می‌دهند.اگر آرایه ، در پشته به همراه یک متغیر در حافظه که بلافاصله در کنار آرایه قرار داده شده ساخته شده باشد، می‌توان خارج از آرایه‌ را اندیس‌گذاری کرد و با تغییر مقدار عنصر مربوط در آرایه (با اندیس مدنظر که از حدود اولیه‌ی آرایه تجاوز می‌کند)، مقدار متغیر مدنظر را تغییر داد. برای مثال، اگر آرایه‌ای از نوع int با سایز 2 داشته‌ باشیم (برای مثال به این منظور آن را arr می‌نامیم) که در کنار متغیر دیگری از نوع int (که آن را i می‌نامیم) قرار دارد، arr[2] (یعنی عنصر سوم آرایه) اگر در حافظه نیز arr و i در مجاورت یکدیگر باشند، با i هم‌اثر می‌شود.int main() int arr[2] = { 1, 2 }; int i=10; /* Write beyond the end of arr. Undefined behaviour in standard C, will write to i in some implementations. */ arr[2] = 20; printf("element 0: %d \t", arr[0]); // outputs 1 printf("element 1: %d \t", arr[1]); // outputs 2 printf("element 2: %d \t", arr[2]); // outputs 20, if aliasing occurred printf("i: %d \t\t", i); // might also output 20, not 10, because of aliasing, but the compiler might have i stored in a register and print 10 /* arr size is still 2. */ printf("arr size: %d \n", (sizeof(arr) / sizeof(int)));این موضوع در برخی پیاده‌سازی‌های C به این خاطر که آرایه یک بلوک پیوسته‌ از حافظه است، و عناصر آرایه صرفا بوسیله‌ی آفستی از آدرس شروع بلوک که در اندازه‌ی یک عنصر آن ضرب شده است، ارجاع داده می‌شوند ممکن است. از آن جایی که C هیچ فرآیند بررسی حدودی ندارد، اندیس‌گذاری و آدرس‌دهی خارج از آرایه نیز ممکن است. قابل ذکر است رفتار هم‌اثرسازی فوق‌الذکر یک رفتار تعریف‌نشده است. برخی از پیاده‌سازی‌ها ممکن است در پشته بین آرایه‌ها و متغیرها فاصله ایجاد کنند تا مثلا‌ متغیرها را در مکان‌هایی از حافظه که اندازه‌ای برابر با مضربی از اندازه‌ی کلمه‌ی اصلی معماری دارند، قرار دهند. استاندارد C به طور عمومی مشخص نمی‌کند داده چگونه بایستی در حافظه قرار گیرد.هم‌اثرسازی اشاره‌گرها.یکی دیگر از انواع هم‌اثرسازی که در هر زبانی می‌تواند رخ دهد این است که یک جا از حافظه توسط بیش از یک نام استفاده شود (مثلا بوسیله‌ی اشاره‌گرها). برای مثال الگوریتم جابجایی مقادیر دو خانه (swap) از طریق XOR در C را درنظر بگیرید؛ این الگوریتم فرض می‌کند که دو اشاره‌گری که به آن فرستاده شده‌اند متمایز هستند، اما اگر در واقع برابر باشند (یا نام های مستعار یکدیگر) باشند ، عملکرد درستی نخواهد داشت. این یک مشکل متداول با توابعی است که اشاره‌گر را به عنوان ورودی می‌پذیرند، و ملاحظات میزان پذیرش هم‌اثرسازی در آن‌ها (یا عدم وجود آن) باید با دقت مستندسازی شود، خصوصاً برای توابعی که تغییرات پیچیده‌ای را در بخش‌های حافظه‌ای که به آن‌ها منتقل شده است، انجام می‌دهند.هم‌اثرسازی معین.هم‌اثرسازی کنترل‌شده ممکن است در برخی موارد مطلوب باشد (یعنی هم‌اثرسازی معین، شخص و محدود شده، بر خلاف آن چه که در زبان C در حافظه فعال می‌شود). این یک روش متداول در Fortran است. زبان برنامه‌نویسی Perl در برخی ساختارها مانند حلقه‌ی foreach هم‌اثرسازی را تعیین می‌کند. این روش این امکان را می‌دهد که در یک داده ساختار مشخص با مقدار کم‌تری کد به طور مستقیم تغییر ایجاد شود. برای مثال:my @array = (1, 2, 3);foreach my $element (@array) { # Increment $element, thus automatically # modifying @array, since $element is "aliased" # to each of @array's elements in turn. $element++;print "@array \n";کد بالا در خروجی به ترتیب «2 3 4» را چاپ می‌کند. اگر در بالا از هم‌اثرسازی استفاده نشود، مقدار یک خانه آرایه در متغیر دیگری کپی شده و مقدار کپی تغییر می‌کند.چالش‌ها با بهینه‌سازی.وقتی که هم‌اثرسازی ممکن است، بهینه‌سازها معمولا مجبور به درنظر گرفتن فرضیات محافظه‌کارانه (در مقابل فرضیات قطعی) درباره‌ی متغیرها هستند. برای مثال، دانستن مقدار یک متغیر (مثل این که مقدار x، 5 است) به طور معمول اجازه بهینه‌سازی‌های مشخص (مانند انتشار ثوابت) را می‌دهد. در حالی که، کامپایلر پس از تخصیص مقدار به یک متغیر دیگر نمی‌تواند از این اطلاعات استفاده کند (برای مثال، در C، *y = 10) به این خاطر که ممکن است *y با x هم‌اثر شده باشد. این مساله حتی می‌تواند موردی بعد از تخصیص مقدار باشد مثل y = &amp;x. به عنوان تاثیر این تخصیص مقدار به *y، مقدار x نیز تغییر می‌کند. بنابراین انتشار این اطلاعات که مقدار x، 5 است در عبارات پس از *y = 10 می‌تواند به طور بالقوه نادرست باشد (اگر *y واقعا با x هم‌اثر شده باشد). با این حال، اگر این اطلاعاتی درباره‌ی اشاره‌گرها باشد، فرآیند انتشار ثوابت می‌تواند یک سوال بوجود آورد: x می‌تواند با *y هم‌اثر شده باشد؟ سپس، اگر پاسخ نه باشد، x = 5 می‌تواند به طور قابل اطمینانی انتشار یابد.تاثیر دیگر هم‌اثرسازی بر بهینه‌سازی در فرآیند «ترتیب‌دهی دوباره به کد» است. اگر کامپایلر تصمیم بگیرد که x با *y هم‌اثر نشود، قسمتی از کد که از مقدار x استفاده می‌کند یا آن را تغییر می‌دهد می‌تواند به قبل از *y = 10 منتقل شود، اگر این بتواند برنامه‌ریزی را بهتر کند یا اجازه‌ی بهینه‌سازی‌های حلقه‌ای بیشتری را بدهد.برای امکان استفاده از چنین بهینه‌سازی‌هایی در شیوه‌ای قابل پیش‌بینی، استاندارد ISO برای زبان برنامه‌نویسی C مشخص می‌کند که (با درنظر گرفتن چند استثنا) دسترسی به یک مکان یکسان در حافظه با استفاده از اشاره‌گرهایی از انواع مختلف غیرمجاز است. در نتیجه یک کامپایلر ممکن است فرض کند چنین اشاره‌گرهایی هم‌اثر نیستند. این قانون، که به «قانون هم‌اثرسازی محض» شناخته می‌شود، گاهی اوقات امکان افزایش موثر بازده را فراهم می‌کند،اما به شکستن و جلوگیری از تولید برخی کدهای معتبر دیگر شناخته می‌شود. پروژه‌های نرم‌افزاری مختلفی در دنیا هستند که این بخش از استاندارد C99 را نقض می‌کنند. برای مثال، Python 2.x این کار را با پیاده‌سازی شمارش مراجع انجام داد، و برای این که امکان این بهینه‌سازی وجود داشته باشد نیازمند تغییر در ساختارهای پایه در Python 3 بود. هسته‌ی لینوکس نیز همین طور بود زیرا هم‌اثرسازی محض باعث مشکلاتی در بهینه‌سازی کدهای درون‌خطی می‌شد. در چنین مواردی، وقتی با gcc کامپایل می‌کنید، گزینه‌ی -fno-strict-aliasing برای جلوگیری از بهینه‌سازی‌های ناخواسته که می‌توانند باعث تولید کدهای پیش‌بینی نشده شوند، فراخوانی می‌شود.پیوند به بیرون.__تغییرمسیرثابت__